diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 97feb494c..926d28345 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -134,7 +134,7 @@ IF(FINAL_VERSION) ENDIF(FINAL_VERSION) IF(WITH_QT) - FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtXml REQUIRED) + FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtXml QtOpenGL REQUIRED) ENDIF(WITH_QT) IF(WITH_NEL) @@ -144,11 +144,6 @@ IF(WITH_NEL) IF(WITH_GUI) FIND_PACKAGE(Libwww REQUIRED) - IF(WITH_LUA51) - FIND_PACKAGE(Lua51 REQUIRED) - ELSE(WITH_LUA51) - FIND_PACKAGE(Lua50 REQUIRED) - ENDIF(WITH_LUA51) FIND_PACKAGE(Luabind REQUIRED) FIND_PACKAGE(CURL REQUIRED) diff --git a/code/CMakeModules/FindFreeType.cmake b/code/CMakeModules/FindFreeType.cmake index e15f55793..68a3ccdbd 100644 --- a/code/CMakeModules/FindFreeType.cmake +++ b/code/CMakeModules/FindFreeType.cmake @@ -52,6 +52,7 @@ FIND_LIBRARY(FREETYPE_LIBRARY_RELEASE /opt/csw/lib /opt/lib /usr/freeware/lib64 + /usr/lib/x86_64-linux-gnu ) FIND_LIBRARY(FREETYPE_LIBRARY_DEBUG @@ -67,6 +68,7 @@ FIND_LIBRARY(FREETYPE_LIBRARY_DEBUG /opt/csw/lib /opt/lib /usr/freeware/lib64 + /usr/lib/x86_64-linux-gnu ) IF(FREETYPE_INCLUDE_DIRS) diff --git a/code/CMakeModules/FindLibOVR.cmake b/code/CMakeModules/FindLibOVR.cmake new file mode 100644 index 000000000..1403a4b2c --- /dev/null +++ b/code/CMakeModules/FindLibOVR.cmake @@ -0,0 +1,70 @@ +# - Locate LibOVR library +# This module defines +# LIBOVR_LIBRARIES, the libraries to link against +# LIBOVR_FOUND, if false, do not try to link to LIBOVR +# LIBOVR_INCLUDE_DIR, where to find headers. + +IF(LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIR) + # in cache already + SET(LIBOVR_FIND_QUIETLY TRUE) +ENDIF(LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIR) + +FIND_PATH(LIBOVR_INCLUDE_DIR + OVR.h + PATHS + $ENV{LIBOVR_DIR}/Include + /usr/local/include + /usr/include + /sw/include + /opt/local/include + /opt/csw/include + /opt/include +) + +IF(UNIX) + IF(TARGET_X64) + SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/Linux/Release/x86_64") + ELSE(TARGET_X64) + SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/Linux/Release/i386") + ENDIF(TARGET_X64) +ELSEIF(APPLE) + SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/MacOS/Release") +ELSEIF(WIN32) + IF(TARGET_X64) + SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/x64") + ELSE(TARGET_X64) + SET(LIBOVR_LIBRARY_BUILD_PATH "Lib/Win32") + ENDIF(TARGET_X64) +ENDIF(UNIX) + +FIND_LIBRARY(LIBOVR_LIBRARY + NAMES ovr + PATHS + $ENV{LIBOVR_DIR}/${LIBOVR_LIBRARY_BUILD_PATH} + /usr/local/lib + /usr/lib + /usr/local/X11R6/lib + /usr/X11R6/lib + /sw/lib + /opt/local/lib + /opt/csw/lib + /opt/lib + /usr/freeware/lib64 +) + +IF(LIBOVR_LIBRARY AND LIBOVR_INCLUDE_DIR) + IF(NOT LIBOVR_FIND_QUIETLY) + MESSAGE(STATUS "Found LibOVR: ${LIBOVR_LIBRARY}") + ENDIF(NOT LIBOVR_FIND_QUIETLY) + SET(LIBOVR_FOUND "YES") + SET(LIBOVR_DEFINITIONS "-DHAVE_LIBOVR") + IF(UNIX) + SET(LIBOVR_LIBRARIES ${LIBOVR_LIBRARY} X11 Xinerama udev pthread) + ELSE(UNIX) + SET(LIBOVR_LIBRARIES ${LIBOVR_LIBRARY}) + ENDIF(UNIX) +ELSE(LIBOVR_LIBRARY AND LIBOVR_INCLUDE_DIR) + IF(NOT LIBOVR_FIND_QUIETLY) + MESSAGE(STATUS "Warning: Unable to find LibOVR!") + ENDIF(NOT LIBOVR_FIND_QUIETLY) +ENDIF(LIBOVR_LIBRARY AND LIBOVR_INCLUDE_DIR) diff --git a/code/CMakeModules/FindLibVR.cmake b/code/CMakeModules/FindLibVR.cmake new file mode 100644 index 000000000..eba9c347e --- /dev/null +++ b/code/CMakeModules/FindLibVR.cmake @@ -0,0 +1,32 @@ +# - Locate LibVR library +# This module defines +# LIBVR_LIBRARIES, the libraries to link against +# LIBVR_FOUND, if false, do not try to link to LIBVR +# LIBVR_INCLUDE_DIR, where to find headers. + +IF(LIBVR_LIBRARIES AND LIBVR_INCLUDE_DIR) + # in cache already + SET(LIBVR_FIND_QUIETLY TRUE) +ENDIF(LIBVR_LIBRARIES AND LIBVR_INCLUDE_DIR) + +FIND_PATH(LIBVR_INCLUDE_DIR hmd.h + PATH_SUFFIXES include/LibVR +) + +FIND_LIBRARY(LIBVR_LIBRARY + NAMES vr + PATH_SUFFIXES lib + PATHS +) + +IF(LIBVR_LIBRARY AND LIBVR_INCLUDE_DIR) + IF(NOT LIBVR_FIND_QUIETLY) + MESSAGE(STATUS "Found LibVR: ${LIBVR_LIBRARY}") + ENDIF(NOT LIBVR_FIND_QUIETLY) + SET(LIBVR_FOUND "YES") + SET(LIBVR_DEFINITIONS "-DHAVE_LIBVR") +ELSE(LIBVR_LIBRARY AND LIBVR_INCLUDE_DIR) + IF(NOT LIBVR_FIND_QUIETLY) + MESSAGE(STATUS "Warning: Unable to find LibVR!") + ENDIF(NOT LIBVR_FIND_QUIETLY) +ENDIF(LIBVR_LIBRARY AND LIBVR_INCLUDE_DIR) diff --git a/code/CMakeModules/FindLua52.cmake b/code/CMakeModules/FindLua52.cmake new file mode 100644 index 000000000..0c25ea840 --- /dev/null +++ b/code/CMakeModules/FindLua52.cmake @@ -0,0 +1,81 @@ +# Locate Lua library +# This module defines +# LUA52_FOUND, if false, do not try to link to Lua +# LUA_LIBRARIES +# LUA_INCLUDE_DIR, where to find lua.h +# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8) +# +# Note that the expected include convention is +# #include "lua.h" +# and not +# #include +# This is because, the lua location is not standardized and may exist +# in locations other than lua/ + +#============================================================================= +# Copyright 2007-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +find_path(LUA_INCLUDE_DIR lua.h + HINTS + ENV LUA_DIR + PATH_SUFFIXES include/lua52 include/lua5.2 include/lua-5.2 include/lua include + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) + +find_library(LUA_LIBRARY + NAMES lua52 lua5.2 lua-5.2 lua + HINTS + ENV LUA_DIR + PATH_SUFFIXES lib + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw + /opt/local + /opt/csw + /opt +) + +if(LUA_LIBRARY) + # include the math library for Unix + if(UNIX AND NOT APPLE AND NOT BEOS) + find_library(LUA_MATH_LIBRARY m) + set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries") + # For Windows and Mac, don't need to explicitly include the math library + else() + set( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries") + endif() +endif() + +if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h") + file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"") + + string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}") + unset(lua_version_str) +endif() + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if +# all listed variables are TRUE +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua52 + REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR + VERSION_VAR LUA_VERSION_STRING) + +mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY) + diff --git a/code/CMakeModules/FindLuabind.cmake b/code/CMakeModules/FindLuabind.cmake index c94a61e30..f61885be8 100644 --- a/code/CMakeModules/FindLuabind.cmake +++ b/code/CMakeModules/FindLuabind.cmake @@ -4,6 +4,48 @@ # LUABIND_FOUND, if false, do not try to link to LUABIND # LUABIND_INCLUDE_DIR, where to find headers. +MACRO(FIND_CORRECT_LUA_VERSION) + # Check Lua version linked to Luabind under Linux + IF(LUABIND_LIBRARY_RELEASE MATCHES "\\.so") + INCLUDE(CheckDepends) + + SET(LUA52_LIBRARY "liblua5.2") + CHECK_LINKED_LIBRARY(LUABIND_LIBRARY_RELEASE LUA52_LIBRARY LUALIB_FOUND) + + IF(LUALIB_FOUND) + MESSAGE(STATUS "Luabind is using Lua 5.2") + FIND_PACKAGE(Lua52 REQUIRED) + ELSE(LUALIB_FOUND) + SET(LUA51_LIBRARY "liblua5.1") + CHECK_LINKED_LIBRARY(LUABIND_LIBRARY_RELEASE LUA51_LIBRARY LUALIB_FOUND) + + IF(LUALIB_FOUND) + MESSAGE(STATUS "Luabind is using Lua 5.1") + FIND_PACKAGE(Lua51 REQUIRED) + ELSE(LUALIB_FOUND) + SET(LUA50_LIBRARY "liblua5.0") + CHECK_LINKED_LIBRARY(LUABIND_LIBRARY_RELEASE LUA50_LIBRARY LUALIB_FOUND) + + IF(LUALIB_FOUND) + MESSAGE(STATUS "Luabind is using Lua 5.0") + FIND_PACKAGE(Lua50 REQUIRED) + ELSE(LUALIB_FOUND) + MESSAGE(FATAL_ERROR "Can't determine Lua version used by Luabind") + ENDIF(LUALIB_FOUND) + ENDIF(LUALIB_FOUND) + ENDIF(LUALIB_FOUND) + ELSE(LUABIND_LIBRARY_RELEASE MATCHES "\\.so") + # TODO: find a way to detect Lua version + IF(WITH_LUA52) + FIND_PACKAGE(Lua52 REQUIRED) + ELSEIF(WITH_LUA51) + FIND_PACKAGE(Lua51 REQUIRED) + ELSE(WITH_LUA52) + FIND_PACKAGE(Lua50 REQUIRED) + ENDIF(WITH_LUA52) + ENDIF(LUABIND_LIBRARY_RELEASE MATCHES "\\.so") +ENDMACRO(FIND_CORRECT_LUA_VERSION) + IF(LUABIND_LIBRARIES AND LUABIND_INCLUDE_DIR) # in cache already SET(Luabind_FIND_QUIETLY TRUE) @@ -84,6 +126,9 @@ IF(LUABIND_FOUND) IF(LUABIND_VERSION_FILE) SET(LUABIND_DEFINITIONS "-DHAVE_LUABIND_VERSION") ENDIF(LUABIND_VERSION_FILE) + + FIND_CORRECT_LUA_VERSION() + IF(NOT Luabind_FIND_QUIETLY) MESSAGE(STATUS "Found Luabind: ${LUABIND_LIBRARIES}") ENDIF(NOT Luabind_FIND_QUIETLY) diff --git a/code/CMakeModules/FindMSVC.cmake b/code/CMakeModules/FindMSVC.cmake index 822e752dd..16455b02d 100644 --- a/code/CMakeModules/FindMSVC.cmake +++ b/code/CMakeModules/FindMSVC.cmake @@ -19,8 +19,13 @@ MACRO(DETECT_VC_VERSION_HELPER _ROOT _VERSION) IF(VC${_VERSION}_DIR AND NOT VC${_VERSION}_DIR STREQUAL "/registry") SET(VC${_VERSION}_FOUND ON) + DETECT_EXPRESS_VERSION(${_VERSION}) IF(NOT MSVC_FIND_QUIETLY) - MESSAGE(STATUS "Found Visual C++ ${_VERSION} in ${VC${_VERSION}_DIR}") + SET(_VERSION_STR ${_VERSION}) + IF(MSVC_EXPRESS) + SET(_VERSION_STR "${_VERSION_STR} Express") + ENDIF(MSVC_EXPRESS) + MESSAGE(STATUS "Found Visual C++ ${_VERSION_STR} in ${VC${_VERSION}_DIR}") ENDIF(NOT MSVC_FIND_QUIETLY) ELSEIF(VC${_VERSION}_DIR AND NOT VC${_VERSION}_DIR STREQUAL "/registry") SET(VC${_VERSION}_FOUND OFF) @@ -36,13 +41,28 @@ MACRO(DETECT_VC_VERSION _VERSION) DETECT_VC_VERSION_HELPER("HKEY_LOCAL_MACHINE" ${_VERSION}) ENDIF(NOT VC${_VERSION}_FOUND) - IF(NOT VC${_VERSION}_FOUND) + IF(VC${_VERSION}_FOUND) SET(VC_FOUND ON) SET(VC_DIR "${VC${_VERSION}_DIR}") - ENDIF(NOT VC${_VERSION}_FOUND) + ENDIF(VC${_VERSION}_FOUND) ENDMACRO(DETECT_VC_VERSION) -IF(MSVC11) +MACRO(DETECT_EXPRESS_VERSION _VERSION) + GET_FILENAME_COMPONENT(MSVC_EXPRESS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\${_VERSION}\\Setup\\VC;ProductDir]" ABSOLUTE) + + IF(MSVC_EXPRESS AND NOT MSVC_EXPRESS STREQUAL "/registry") + SET(MSVC_EXPRESS ON) + ENDIF(MSVC_EXPRESS AND NOT MSVC_EXPRESS STREQUAL "/registry") +ENDMACRO(DETECT_EXPRESS_VERSION) + +IF(MSVC12) + DETECT_VC_VERSION("12.0") + + IF(NOT MSVC12_REDIST_DIR) + # If you have VC++ 2013 Express, put x64/Microsoft.VC120.CRT/*.dll in ${EXTERNAL_PATH}/redist + SET(MSVC12_REDIST_DIR "${EXTERNAL_PATH}/redist") + ENDIF(NOT MSVC11_REDIST_DIR) +ELSEIF(MSVC11) DETECT_VC_VERSION("11.0") IF(NOT MSVC11_REDIST_DIR) @@ -60,7 +80,7 @@ ELSEIF(MSVC90) DETECT_VC_VERSION("9.0") ELSEIF(MSVC80) DETECT_VC_VERSION("8.0") -ENDIF(MSVC11) +ENDIF(MSVC12) # If you plan to use VC++ compilers with WINE, set VC_DIR environment variable IF(NOT VC_DIR) diff --git a/code/CMakeModules/FindMySQL.cmake b/code/CMakeModules/FindMySQL.cmake index 1da6157fa..eb2102c8d 100644 --- a/code/CMakeModules/FindMySQL.cmake +++ b/code/CMakeModules/FindMySQL.cmake @@ -58,6 +58,8 @@ ELSE(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES) SET(MYSQL_LIBRARIES optimized ${MYSQL_LIBRARY_RELEASE}) IF(MYSQL_LIBRARY_DEBUG) SET(MYSQL_LIBRARIES ${MYSQL_LIBRARIES} debug ${MYSQL_LIBRARY_DEBUG}) + ELSE(MYSQL_LIBRARY_DEBUG) + SET(MYSQL_LIBRARIES ${MYSQL_LIBRARIES} debug ${MYSQL_LIBRARY_RELEASE}) ENDIF(MYSQL_LIBRARY_DEBUG) FIND_PACKAGE(OpenSSL) IF(OPENSSL_FOUND) diff --git a/code/CMakeModules/FindWindowsSDK.cmake b/code/CMakeModules/FindWindowsSDK.cmake index 1b2affb99..fd32d92b5 100644 --- a/code/CMakeModules/FindWindowsSDK.cmake +++ b/code/CMakeModules/FindWindowsSDK.cmake @@ -11,6 +11,7 @@ IF(WINSDK_FOUND) RETURN() ENDIF(WINSDK_FOUND) +# Values can be CURRENT or any existing versions 7.1, 8.0A, etc... SET(WINSDK_VERSION "CURRENT" CACHE STRING "Windows SDK version to prefer") MACRO(DETECT_WINSDK_VERSION_HELPER _ROOT _VERSION) @@ -22,7 +23,7 @@ MACRO(DETECT_WINSDK_VERSION_HELPER _ROOT _VERSION) IF(NOT WindowsSDK_FIND_QUIETLY) MESSAGE(STATUS "Found Windows SDK ${_VERSION} in ${WINSDK${_VERSION}_DIR}") ENDIF(NOT WindowsSDK_FIND_QUIETLY) - ELSEIF(WINSDK${_VERSION}_DIR AND NOT WINSDK${_VERSION}_DIR STREQUAL "/registry") + ELSE(WINSDK${_VERSION}_DIR AND NOT WINSDK${_VERSION}_DIR STREQUAL "/registry") SET(WINSDK${_VERSION}_DIR "") ENDIF(WINSDK${_VERSION}_DIR AND NOT WINSDK${_VERSION}_DIR STREQUAL "/registry") ENDMACRO(DETECT_WINSDK_VERSION_HELPER) @@ -30,17 +31,22 @@ ENDMACRO(DETECT_WINSDK_VERSION_HELPER) MACRO(DETECT_WINSDK_VERSION _VERSION) SET(WINSDK${_VERSION}_FOUND OFF) DETECT_WINSDK_VERSION_HELPER("HKEY_CURRENT_USER" ${_VERSION}) - + IF(NOT WINSDK${_VERSION}_FOUND) DETECT_WINSDK_VERSION_HELPER("HKEY_LOCAL_MACHINE" ${_VERSION}) ENDIF(NOT WINSDK${_VERSION}_FOUND) ENDMACRO(DETECT_WINSDK_VERSION) -SET(WINSDK_VERSIONS "8.0" "8.0A" "7.1" "7.0A" "6.1" "6.0" "6.0A") +SET(WINSDK_VERSIONS "8.0" "8.0A" "7.1" "7.1A" "7.0" "7.0A" "6.1" "6.0" "6.0A") +SET(WINSDK_DETECTED_VERSIONS) # Search all supported Windows SDKs FOREACH(_VERSION ${WINSDK_VERSIONS}) DETECT_WINSDK_VERSION(${_VERSION}) + + IF(WINSDK${_VERSION}_FOUND) + LIST(APPEND WINSDK_DETECTED_VERSIONS ${_VERSION}) + ENDIF(WINSDK${_VERSION}_FOUND) ENDFOREACH(_VERSION) SET(WINSDK_SUFFIX) @@ -54,51 +60,186 @@ ELSEIF(TARGET_X86) SET(WINSDK8_SUFFIX "x86") ENDIF(TARGET_ARM) -GET_FILENAME_COMPONENT(WINSDKCURRENT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentVersion]" NAME) +SET(WINSDKCURRENT_VERSION_INCLUDE $ENV{INCLUDE}) -IF(WINSDKCURRENT_VERSION AND NOT WINSDKCURRENT_VERSION STREQUAL "/registry") - IF(NOT WindowsSDK_FIND_QUIETLY) -# MESSAGE(STATUS "Current version is ${WINSDKCURRENT_VERSION}") - ENDIF(NOT WindowsSDK_FIND_QUIETLY) -ENDIF(WINSDKCURRENT_VERSION AND NOT WINSDKCURRENT_VERSION STREQUAL "/registry") +IF(WINSDKCURRENT_VERSION_INCLUDE) + FILE(TO_CMAKE_PATH "${WINSDKCURRENT_VERSION_INCLUDE}" WINSDKCURRENT_VERSION_INCLUDE) +ENDIF(WINSDKCURRENT_VERSION_INCLUDE) SET(WINSDKENV_DIR $ENV{WINSDK_DIR}) +MACRO(FIND_WINSDK_VERSION_HEADERS) + IF(WINSDK_DIR AND NOT WINSDK_VERSION) + # Search version in headers + IF(EXISTS ${WINSDK_DIR}/include/Msi.h) + SET(_MSI_FILE ${WINSDK_DIR}/include/Msi.h) + ENDIF(EXISTS ${WINSDK_DIR}/include/Msi.h) + + IF(_MSI_FILE) + # Look for Windows SDK 8.0 + FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN8") + + IF(_CONTENT) + SET(WINSDK_VERSION "8.0") + ENDIF(_CONTENT) + + IF(NOT WINSDK_VERSION) + # Look for Windows SDK 7.0 + FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN7") + + IF(_CONTENT) + IF(EXISTS ${WINSDK_DIR}/include/winsdkver.h) + SET(_WINSDKVER_FILE ${WINSDK_DIR}/include/winsdkver.h) + ELSEIF(EXISTS ${WINSDK_DIR}/include/WinSDKVer.h) + SET(_WINSDKVER_FILE ${WINSDK_DIR}/include/WinSDKVer.h) + ENDIF(EXISTS ${WINSDK_DIR}/include/winsdkver.h) + + IF(_WINSDKVER_FILE) + # Load WinSDKVer.h content + FILE(STRINGS ${_WINSDKVER_FILE} _CONTENT REGEX "^#define NTDDI_MAXVER") + + # Get NTDDI_MAXVER value + STRING(REGEX REPLACE "^.*0x([0-9A-Fa-f]+).*$" "\\1" _WINSDKVER "${_CONTENT}") + + # In Windows SDK 7.1, NTDDI_MAXVER is wrong + IF(_WINSDKVER STREQUAL "06010000") + SET(WINSDK_VERSION "7.1") + ELSEIF(_WINSDKVER STREQUAL "0601") + SET(WINSDK_VERSION "7.0A") + ELSE(_WINSDKVER STREQUAL "06010000") + MESSAGE(FATAL_ERROR "Can't determine Windows SDK version with NTDDI_MAXVER 0x${_WINSDKVER}") + ENDIF(_WINSDKVER STREQUAL "06010000") + ELSE(_WINSDKVER_FILE) + SET(WINSDK_VERSION "7.0") + ENDIF(_WINSDKVER_FILE) + ENDIF(_CONTENT) + ENDIF(NOT WINSDK_VERSION) + + IF(NOT WINSDK_VERSION) + # Look for Windows SDK 6.0 + FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_VISTA") + + IF(_CONTENT) + SET(WINSDK_VERSION "6.0") + ENDIF(_CONTENT) + ENDIF(NOT WINSDK_VERSION) + + IF(NOT WINSDK_VERSION) + # Look for Windows SDK 5.2 + FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WS03SP1") + + IF(_CONTENT) + SET(WINSDK_VERSION "5.2") + ENDIF(_CONTENT) + ENDIF(NOT WINSDK_VERSION) + + IF(NOT WINSDK_VERSION) + # Look for Windows SDK 5.1 + FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WINXP") + + IF(_CONTENT) + SET(WINSDK_VERSION "5.1") + ENDIF(_CONTENT) + ENDIF(NOT WINSDK_VERSION) + + IF(NOT WINSDK_VERSION) + # Look for Windows SDK 5.0 + FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN2K") + + IF(_CONTENT) + SET(WINSDK_VERSION "5.0") + ENDIF(_CONTENT) + ENDIF(NOT WINSDK_VERSION) + ELSE(_MSI_FILE) + MESSAGE(FATAL_ERROR "Unable to find Msi.h in ${WINSDK_DIR}") + ENDIF(_MSI_FILE) + ENDIF(WINSDK_DIR AND NOT WINSDK_VERSION) +ENDMACRO(FIND_WINSDK_VERSION_HEADERS) + MACRO(USE_CURRENT_WINSDK) - IF(WINSDKENV_DIR) - SET(WINSDK_VERSION "") - SET(WINSDK_VERSION_FULL "") + SET(WINSDK_DIR "") + SET(WINSDK_VERSION "") + SET(WINSDK_VERSION_FULL "") + + # Use WINSDK environment variable + IF(WINSDKENV_DIR AND EXISTS ${WINSDKENV_DIR}/include/Windows.h) SET(WINSDK_DIR ${WINSDKENV_DIR}) - FOREACH(_VERSION ${WINSDK_VERSIONS}) - IF(WINSDK_DIR STREQUAL WINSDK${_VERSION}_DIR) + ENDIF(WINSDKENV_DIR AND EXISTS ${WINSDKENV_DIR}/include/Windows.h) + + # Use INCLUDE environment variable + IF(NOT WINSDK_DIR AND WINSDKCURRENT_VERSION_INCLUDE) + FOREACH(_INCLUDE ${WINSDKCURRENT_VERSION_INCLUDE}) + FILE(TO_CMAKE_PATH ${_INCLUDE} _INCLUDE) + + # Look for Windows.h because there are several paths + IF(EXISTS ${_INCLUDE}/Windows.h) + STRING(REGEX REPLACE "/(include|INCLUDE|Include)" "" WINSDK_DIR ${_INCLUDE}) + MESSAGE(STATUS "Found Windows SDK environment variable in ${WINSDK_DIR}") + BREAK() + ENDIF(EXISTS ${_INCLUDE}/Windows.h) + ENDFOREACH(_INCLUDE) + ENDIF(NOT WINSDK_DIR AND WINSDKCURRENT_VERSION_INCLUDE) + + IF(WINSDK_DIR) + # Compare WINSDK_DIR with registered Windows SDKs + FOREACH(_VERSION ${WINSDK_DETECTED_VERSIONS}) + IF(WINSDK_DIR STREQUAL "${WINSDK${_VERSION}_DIR}") SET(WINSDK_VERSION ${_VERSION}) - SET(WINSDK_VERSION_FULL "${WINSDK${_VERSION}_VERSION_FULL}") + SET(WINSDK_VERSION_FULL "${WINSDK${WINSDK_VERSION}_VERSION_FULL}") BREAK() - ENDIF(WINSDK_DIR STREQUAL WINSDK${_VERSION}_DIR) + ENDIF(WINSDK_DIR STREQUAL "${WINSDK${_VERSION}_DIR}") ENDFOREACH(_VERSION) - ELSE(WINSDKENV_DIR) - # Windows SDK 7.0A doesn't provide 64bits compilers, use SDK 7.1 for 64 bits - IF(WINSDKCURRENT_VERSION STREQUAL WINSDK7.0A_VERSION_FULL) - IF(TARGET_X64) - SET(WINSDK_VERSION "7.1") - SET(WINSDK_VERSION_FULL ${WINSDK7.1_VERSION_FULL}) - SET(WINSDK_DIR ${WINSDK7.1_DIR}) - ELSE(TARGET_X64) + + FIND_WINSDK_VERSION_HEADERS() + ENDIF(WINSDK_DIR) + + IF(NOT WINSDK_DIR) + # Use Windows SDK versions installed with VC++ when possible + IF(MSVC12) + SET(WINSDK_VERSION "8.1A") + ELSEIF(MSVC11) + SET(WINSDK_VERSION "8.0A") + ELSEIF(MSVC10) + IF(NOT TARGET_X64 OR NOT MSVC_EXPRESS) SET(WINSDK_VERSION "7.0A") - SET(WINSDK_VERSION_FULL ${WINSDK7.0A_VERSION_FULL}) - SET(WINSDK_DIR ${WINSDK7.0A_DIR}) - ENDIF(TARGET_X64) - ELSE(WINSDKCURRENT_VERSION STREQUAL WINSDK7.0A_VERSION_FULL) - FOREACH(_VERSION ${WINSDK_VERSIONS}) - IF(WINSDKCURRENT_VERSION STREQUAL WINSDK${_VERSION}_VERSION) - SET(WINSDK_VERSION ${_VERSION}) - SET(WINSDK_VERSION_FULL "${WINSDK${_VERSION}_VERSION_FULL}") - SET(WINSDK_DIR "${WINSDK${_VERSION}_DIR}") - BREAK() - ENDIF(WINSDKCURRENT_VERSION STREQUAL WINSDK${_VERSION}_VERSION) - ENDFOREACH(_VERSION) - ENDIF(WINSDKCURRENT_VERSION STREQUAL WINSDK7.0A_VERSION_FULL) - ENDIF(WINSDKENV_DIR) + ENDIF(NOT TARGET_X64 OR NOT MSVC_EXPRESS) + ELSEIF(MSVC90) + IF(NOT MSVC_EXPRESS) + SET(WINSDK_VERSION "6.0A") + ENDIF(NOT MSVC_EXPRESS) + ELSEIF(MSVC80) + IF(NOT MSVC_EXPRESS) + # TODO: fix this version + SET(WINSDK_VERSION "5.2A") + ENDIF(NOT MSVC_EXPRESS) + ELSE(MSVC12) + MESSAGE(FATAL_ERROR "Your compiler is either too old or too recent, please update this CMake module.") + ENDIF(MSVC12) + + # Use installed Windows SDK + IF(NOT WINSDK_VERSION) + IF(WINSDK7.1_FOUND) + SET(WINSDK_VERSION "7.1") + ELSEIF(WINSDK7.0_FOUND) + SET(WINSDK_VERSION "7.0") + ELSEIF(WINSDK6.1_FOUND) + SET(WINSDK_VERSION "6.1") + ELSEIF(WINSDK6.0_FOUND) + SET(WINSDK_VERSION "6.0") + ELSE(WINSDK7.1_FOUND) + MESSAGE(FATAL_ERROR "You have no compatible Windows SDK installed.") + ENDIF(WINSDK7.1_FOUND) + ENDIF(NOT WINSDK_VERSION) + + # Look for correct registered Windows SDK version + FOREACH(_VERSION ${WINSDK_DETECTED_VERSIONS}) + IF(WINSDK_VERSION STREQUAL _VERSION) + SET(WINSDK_VERSION_FULL "${WINSDK${WINSDK_VERSION}_VERSION_FULL}") + SET(WINSDK_DIR "${WINSDK${WINSDK_VERSION}_DIR}") + BREAK() + ENDIF(WINSDK_VERSION STREQUAL _VERSION) + ENDFOREACH(_VERSION) + ENDIF(NOT WINSDK_DIR) ENDMACRO(USE_CURRENT_WINSDK) IF(WINSDK_VERSION STREQUAL "CURRENT") diff --git a/code/CMakeModules/PCHSupport.cmake b/code/CMakeModules/PCHSupport.cmake index 9033f6583..97b5ed88d 100644 --- a/code/CMakeModules/PCHSupport.cmake +++ b/code/CMakeModules/PCHSupport.cmake @@ -273,15 +273,22 @@ MACRO(ADD_PRECOMPILED_HEADER_TO_TARGET _targetName) # Ninja PCH Support # http://public.kitware.com/pipermail/cmake-developers/2012-March/003653.html SET_TARGET_PROPERTIES(${_targetName} PROPERTIES OBJECT_DEPENDS "${PCH_OUTPUT}") - + # NMAKE-VS2012 Error LNK2011 (NMAKE-VS2010 do not complain) # we need to link the pch.obj file, see http://msdn.microsoft.com/en-us/library/3ay26wa2(v=vs.110).aspx - GET_TARGET_PROPERTY(DEPS ${_targetName} LINK_LIBRARIES) - if (NOT DEPS) - set (DEPS) - endif () - list (INSERT DEPS 0 "${PCH_OUTPUT}.obj") - SET_TARGET_PROPERTIES(${_targetName} PROPERTIES LINK_LIBRARIES "${DEPS}") + GET_TARGET_PROPERTY(_STATIC_LIBRARY_FLAGS ${_targetName} STATIC_LIBRARY_FLAGS) + IF(NOT _STATIC_LIBRARY_FLAGS) + SET(_STATIC_LIBRARY_FLAGS) + ENDIF(NOT _STATIC_LIBRARY_FLAGS) + SET(_STATIC_LIBRARY_FLAGS "${PCH_OUTPUT}.obj ${_STATIC_LIBRARY_FLAGS}") + + GET_TARGET_PROPERTY(_LINK_FLAGS ${_targetName} LINK_FLAGS) + IF(NOT _LINK_FLAGS) + SET(_LINK_FLAGS) + ENDIF(NOT _LINK_FLAGS) + SET(_LINK_FLAGS "${PCH_OUTPUT}.obj ${_LINK_FLAGS}") + + SET_TARGET_PROPERTIES(${_targetName} PROPERTIES STATIC_LIBRARY_FLAGS ${_STATIC_LIBRARY_FLAGS} LINK_FLAGS ${_LINK_FLAGS}) ELSE(MSVC) # for use with distcc and gcc >4.0.1 if preprocessed files are accessible # on all remote machines set @@ -369,17 +376,6 @@ MACRO(ADD_PRECOMPILED_HEADER _targetName _inputh _inputcpp) SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PCH_OUTPUTS}") ENDMACRO(ADD_PRECOMPILED_HEADER) -# Macro to move PCH creation file to the front of files list -# or remove .cpp from library/executable to avoid warning -MACRO(FIX_PRECOMPILED_HEADER _files _pch) - # Remove .cpp creating PCH from the list - LIST(REMOVE_ITEM ${_files} ${_pch}) - IF(MSVC) - # Prepend .cpp creating PCH to the list - LIST(INSERT ${_files} 0 ${_pch}) - ENDIF(MSVC) -ENDMACRO(FIX_PRECOMPILED_HEADER) - MACRO(ADD_NATIVE_PRECOMPILED_HEADER _targetName _inputh _inputcpp) IF(NOT PCHSupport_FOUND) MESSAGE(STATUS "PCH disabled because compiler doesn't support them") @@ -391,10 +387,6 @@ MACRO(ADD_NATIVE_PRECOMPILED_HEADER _targetName _inputh _inputcpp) # 2 => setting PCH for XCode project, works for XCode projects IF(CMAKE_GENERATOR MATCHES "Visual Studio") SET(PCH_METHOD 1) - ELSEIF(CMAKE_GENERATOR MATCHES "NMake Makefiles" AND MFC_FOUND AND CMAKE_MFC_FLAG) - # To fix a bug with MFC - # Don't forget to use FIX_PRECOMPILED_HEADER before creating the target -# SET(PCH_METHOD 1) ELSEIF(CMAKE_GENERATOR MATCHES "Xcode") SET(PCH_METHOD 2) ELSE(CMAKE_GENERATOR MATCHES "Visual Studio") diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index eab6404ac..12cf6b9b5 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -329,6 +329,9 @@ MACRO(NL_SETUP_NEL_DEFAULT_OPTIONS) OPTION(WITH_NEL_MAXPLUGIN "Build NeL 3dsMax Plugin" OFF) OPTION(WITH_NEL_SAMPLES "Build NeL Samples" ON ) OPTION(WITH_NEL_TESTS "Build NeL Unit Tests" ON ) + + OPTION(WITH_LIBOVR "With LibOVR support" OFF) + OPTION(WITH_LIBVR "With LibVR support" OFF) ENDMACRO(NL_SETUP_NEL_DEFAULT_OPTIONS) MACRO(NL_SETUP_NELNS_DEFAULT_OPTIONS) @@ -351,7 +354,8 @@ MACRO(NL_SETUP_RYZOM_DEFAULT_OPTIONS) ### # Optional support ### - OPTION(WITH_LUA51 "Build Ryzom Core using Lua51" ON ) + OPTION(WITH_LUA51 "Build Ryzom Core using Lua 5.1" ON ) + OPTION(WITH_LUA52 "Build Ryzom Core using Lua 5.2" OFF) ENDMACRO(NL_SETUP_RYZOM_DEFAULT_OPTIONS) MACRO(NL_SETUP_SNOWBALLS_DEFAULT_OPTIONS) diff --git a/code/nel/CMakeLists.txt b/code/nel/CMakeLists.txt index 1929135b4..53bf071e3 100644 --- a/code/nel/CMakeLists.txt +++ b/code/nel/CMakeLists.txt @@ -41,6 +41,14 @@ IF(WITH_GTK) FIND_PACKAGE(GTK2) ENDIF(WITH_GTK) +IF(WITH_LIBOVR) + FIND_PACKAGE(LibOVR) +ENDIF(WITH_LIBOVR) + +IF(WITH_LIBVR) + FIND_PACKAGE(LibVR) +ENDIF(WITH_LIBVR) + IF(WITH_INSTALL_LIBRARIES) IF(UNIX) SET(prefix ${CMAKE_INSTALL_PREFIX}) diff --git a/code/nel/include/nel/3d/bloom_effect.h b/code/nel/include/nel/3d/bloom_effect.h index 77673741c..c10967254 100644 --- a/code/nel/include/nel/3d/bloom_effect.h +++ b/code/nel/include/nel/3d/bloom_effect.h @@ -138,6 +138,8 @@ private: NLMISC::CSmartPtr _BlurFinalTex; // used as render target in first blur pass, and as displayed texture on second blur pass. NLMISC::CSmartPtr _BlurHorizontalTex; + // original render target + NLMISC::CSmartPtr _OriginalRenderTarget; // materials diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index 805c4096c..a072abfbd 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -26,10 +26,12 @@ #include "nel/misc/uv.h" #include "nel/misc/hierarchical_timer.h" #include "nel/3d/texture.h" -#include "nel/3d/shader.h" #include "nel/3d/vertex_buffer.h" #include "nel/3d/index_buffer.h" #include "nel/3d/vertex_program.h" +#include "nel/3d/pixel_program.h" +#include "nel/3d/geometry_program.h" +#include "nel/3d/gpu_program_params.h" #include "nel/3d/material.h" #include "nel/misc/mutex.h" #include "nel/3d/primitive_profile.h" @@ -105,7 +107,6 @@ struct EBadDisplay : public NLMISC::Exception typedef void (*emptyProc)(void); class IProgram; -class IProgramObject; // **************************************************************************** // *** IMPORTANT ******************** @@ -122,9 +123,9 @@ public: static const uint32 InterfaceVersion; public: - enum TMessageBoxId { okId=0, yesId, noId, abortId, retryId, cancelId, ignoreId, idCount }; - enum TMessageBoxType { okType=0, okCancelType, yesNoType, abortRetryIgnoreType, yesNoCancelType, retryCancelType, typeCount }; - enum TMessageBoxIcon { noIcon=0, handIcon, questionIcon, exclamationIcon, asteriskIcon, warningIcon, errorIcon, informationIcon, stopIcon, iconCount }; + enum TMessageBoxId { okId = 0, yesId, noId, abortId, retryId, cancelId, ignoreId, idCount }; + enum TMessageBoxType { okType = 0, okCancelType, yesNoType, abortRetryIgnoreType, yesNoCancelType, retryCancelType, typeCount }; + enum TMessageBoxIcon { noIcon = 0, handIcon, questionIcon, exclamationIcon, asteriskIcon, warningIcon, errorIcon, informationIcon, stopIcon, iconCount }; enum TCullMode { CCW = 0, CW }; enum TStencilOp { keep = 0, zero, replace, incr, decr, invert }; enum TStencilFunc { never = 0, less, lessequal, equal, notequal, greaterequal, greater, always}; @@ -134,117 +135,225 @@ public: * * \see setPolygonMode, getPolygonMode */ - enum TPolygonMode { Filled=0, Line, Point }; - + enum TPolygonMode { Filled = 0, Line, Point }; /** * Driver Max matrix count. * Kept for backward compatibility. Suppose any Hardware VertexProgram can handle only 16 matrix * */ - enum TMatrixCount { MaxModelMatrix= 16 }; + enum TMatrixCount { MaxModelMatrix = 16 }; + enum TMatrix + { + ModelView= 0, + Projection, + ModelViewProjection, + NumMatrix + }; -protected: + enum TTransform + { + Identity=0, + Inverse, + Transpose, + InverseTranspose, + NumTransform + }; - CSynchronized _SyncTexDrvInfos; + enum TProgram + { + VertexProgram = 0, + PixelProgram = 1, + GeometryProgram = 2 + }; + +protected: + CSynchronized _SyncTexDrvInfos; + TTexDrvSharePtrList _TexDrvShares; + TMatDrvInfoPtrList _MatDrvInfos; + TVBDrvInfoPtrList _VBDrvInfos; + TIBDrvInfoPtrList _IBDrvInfos; + TGPUPrgDrvInfoPtrList _GPUPrgDrvInfos; - TTexDrvSharePtrList _TexDrvShares; - TMatDrvInfoPtrList _MatDrvInfos; - TVBDrvInfoPtrList _VBDrvInfos; - TIBDrvInfoPtrList _IBDrvInfos; TPolygonMode _PolygonMode; - TVtxPrgDrvInfoPtrList _VtxPrgDrvInfos; - TShaderDrvInfoPtrList _ShaderDrvInfos; uint _ResetCounter; public: - IDriver(void); - virtual ~IDriver(void); + IDriver(); + virtual ~IDriver(); + + virtual bool init(uint windowIcon = 0, emptyProc exitFunc = 0) = 0; + + /// Deriver should calls IDriver::release() first, to destroy all driver components (textures, shaders, VBuffers). + virtual bool release(); - virtual bool init (uint windowIcon = 0, emptyProc exitFunc = 0)=0; + /// Before rendering via a driver in a thread, must activate() (per thread). + virtual bool activate() = 0; // Test if the device is lost. Can only happen with D3D. // The calling application may skip some part of its rendering when it is the case (this is not a requirement, but may save cpu for other applications) virtual bool isLost() const = 0; + /// Return true if driver is still active. Return false else. If he user close the window, must return false. + virtual bool isActive() = 0; + + + + /** Return the driver reset counter. + * The reset counter is incremented at each driver reset. + */ + uint getResetCounter() const { return _ResetCounter; } + + // get the number of call to swapBuffer since the driver was created + virtual uint64 getSwapBufferCounter() const = 0; + + + /// \name Disable Hardware Feature /** Disable some Feature that may be supported by the Hardware * Call before setDisplay() to work properly */ // @{ - virtual void disableHardwareVertexProgram()=0; - virtual void disableHardwareVertexArrayAGP()=0; - virtual void disableHardwareTextureShader()=0; + virtual void disableHardwareVertexProgram() = 0; + virtual void disableHardwarePixelProgram() = 0; + virtual void disableHardwareVertexArrayAGP() = 0; + virtual void disableHardwareTextureShader() = 0; // @} + + + /// \name Windowing + // @{ // first param is the associated window. // Must be a HWND for Windows (WIN32). - virtual bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show = true, bool resizeable = true) throw(EBadDisplay)=0; + virtual bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show = true, bool resizeable = true) throw(EBadDisplay) = 0; // Must be called after a setDisplay that initialize the mode - virtual bool setMode(const GfxMode& mode)=0; - virtual bool getModes(std::vector &modes)=0; + virtual bool setMode(const GfxMode &mode) = 0; + virtual bool getModes(std::vector &modes) = 0; /// Set the title of the NeL window - virtual void setWindowTitle(const ucstring &title)=0; - + virtual void setWindowTitle(const ucstring &title) = 0; /// Set icon(s) of the NeL window - virtual void setWindowIcon(const std::vector &bitmaps)=0; - + virtual void setWindowIcon(const std::vector &bitmaps) = 0; /// Set the position of the NeL window - virtual void setWindowPos(sint32 x, sint32 y)=0; - + virtual void setWindowPos(sint32 x, sint32 y) = 0; /// Show or hide the NeL window - virtual void showWindow(bool show)=0; + virtual void showWindow(bool show) = 0; /// return the current screen mode (if we are in windowed, return the screen mode behind the window) - virtual bool getCurrentScreenMode(GfxMode &mode)=0; + virtual bool getCurrentScreenMode(GfxMode &mode) = 0; /// enter/leave the dialog mode - virtual void beginDialogMode() =0; - virtual void endDialogMode() =0; + virtual void beginDialogMode() = 0; + virtual void endDialogMode() = 0; // Return is the associated window information. (Implementation dependent) // Must be a HWND for Windows (WIN32). - virtual nlWindow getDisplay() =0; + virtual nlWindow getDisplay() = 0; - /** - * Setup monitor color properties. - * - * Return false if setup failed. - */ - virtual bool setMonitorColorProperties (const CMonitorColorProperties &properties) = 0; + /// Setup monitor color properties. Return false if setup failed + virtual bool setMonitorColorProperties(const CMonitorColorProperties &properties) = 0; // Return is the associated default window proc for the driver. (Implementation dependent) // Must be a void GlWndProc(IDriver *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) for Windows (WIN32). virtual emptyProc getWindowProc() = 0; - /// Before rendering via a driver in a thread, must activate() (per thread). - virtual bool activate(void) = 0; + virtual NLMISC::IEventEmitter *getEventEmitter() = 0; + + /// Copy a string to system clipboard. + virtual bool copyTextToClipboard(const ucstring &text) = 0; - /// Get the number of texture stage available, for multi texturing (Normal material shaders). Valid only after setDisplay(). - virtual uint getNbTextureStages() const = 0; + /// Paste a string from system clipboard. + virtual bool pasteTextFromClipboard(ucstring &text) = 0;/// Return the depth of the driver after init(). - /** is the texture is set up in the driver - * NB: this method is thread safe. - */ - virtual bool isTextureExist(const ITexture&tex)=0; + virtual uint8 getBitPerPixel() = 0; + + /** Output a system message box and print a message with an icon. This method can be call even if the driver is not initialized. + * This method is used to return internal driver problem when string can't be displayed in the driver window. + * If the driver can't open a messageBox, it should not override this method and let the IDriver class manage it with the ASCII console. + * + * \param message This is the message to display in the message box. + * \param title This is the title of the message box. + * \param type This is the type of the message box, ie number of button and label of buttons. + * \param icon This is the icon of the message box should use like warning, error etc... + */ + virtual TMessageBoxId systemMessageBox(const char *message, const char *title, TMessageBoxType type = okType, TMessageBoxIcon icon = noIcon); + + /// Get the width and the height of the window + virtual void getWindowSize(uint32 &width, uint32 &height) = 0; + + /// Get the position of the window always (0,0) in fullscreen + virtual void getWindowPos(sint32 &x, sint32 &y) = 0; + // @} - virtual NLMISC::IEventEmitter* getEventEmitter(void) = 0; - /* Clear the current target surface pixels. The function ignores the viewport settings but uses the scissor. */ + + /// \name Framebuffer operations + // @{ + /// Clear the current target surface pixels. The function ignores the viewport settings but uses the scissor. virtual bool clear2D(CRGBA rgba) = 0; - /* Clear the current target surface zbuffer. The function ignores the viewport settings but uses the scissor. */ + /// Clear the current target surface zbuffer. The function ignores the viewport settings but uses the scissor. virtual bool clearZBuffer(float zval=1) = 0; - /* Clear the current target surface stencil buffer. The function ignores the viewport settings but uses the scissor. */ + /// Clear the current target surface stencil buffer. The function ignores the viewport settings but uses the scissor. virtual bool clearStencilBuffer(float stencilval=0) = 0; /// Set the color mask filter through where the operation done will pass - virtual void setColorMask (bool bRed, bool bGreen, bool bBlue, bool bAlpha) = 0; + virtual void setColorMask(bool bRed, bool bGreen, bool bBlue, bool bAlpha) = 0; + // @} + + + + /// \name Copy framebuffer to memory + // @{ + /** get the RGBA back buffer. After swapBuffers(), the content of the back buffer is undefined. + * + * \param bitmap the buffer will be written in this bitmap + */ + virtual void getBuffer(CBitmap &bitmap) = 0; + + /** get the ZBuffer (back buffer). + * + * \param zbuffer the returned array of Z. size of getWindowSize() . + */ + virtual void getZBuffer(std::vector &zbuffer) = 0; + + /** get a part of the RGBA back buffer. After swapBuffers(), the content of the back buffer is undefined. + * NB: 0,0 is the bottom left corner of the screen. + * + * \param bitmap the buffer will be written in this bitmap + * \param rect the in/out (wanted/clipped) part of Color buffer to retrieve. + */ + virtual void getBufferPart(CBitmap &bitmap, NLMISC::CRect &rect) = 0; + + /** get a part of the ZBuffer (back buffer). + * NB: 0,0 is the bottom left corner of the screen. + * + * \param zbuffer the returned array of Z. size of rec.Width*rec.Height. + * \param rect the in/out (wanted/clipped) part of ZBuffer to retrieve. + */ + virtual void getZBufferPart(std::vector &zbuffer, NLMISC::CRect &rect) = 0; + // @} + + + /// \name Copy memory to framebuffer + // @{ + /** fill the RGBA back buffer + * + * \param bitmap will be written in the buffer. no-op if bad size. + * \return true if success + */ + virtual bool fillBuffer(CBitmap &bitmap) = 0; + // @} + + + + /// \name Viewport depth clipping + // @{ /** Set depth range. Depth range specify a linear mapping from device z coordinates (in the [-1, 1] range) to window coordinates (in the [0, 1] range) * This mapping occurs after clipping of primitives and division by w of vertices coordinates. * Default depth range is [0, 1]. @@ -253,11 +362,20 @@ public: virtual void setDepthRange(float znear, float zfar) = 0; // Get the current depth range virtual void getDepthRange(float &znear, float &zfar) const = 0; + // @} + + + /// \name Textures + // @{ + /** is the texture is set up in the driver + * NB: this method is thread safe. + */ + virtual bool isTextureExist(const ITexture &tex) = 0; /** setup a texture, generate and upload if needed. same as setupTextureEx(tex, true, dummy); */ - virtual bool setupTexture(ITexture& tex) = 0; + virtual bool setupTexture(ITexture &tex) = 0; /** setup a texture in the driver. * \param bUpload if true the texture is created and uploaded to VRAM, if false the texture is only created @@ -270,64 +388,81 @@ public: * is only bound to tex (thus creating and uploading nothing) * NB: the texture must be at least touch()-ed for the recreate to work. */ - virtual bool setupTextureEx (ITexture& tex, bool bUpload, bool& bAllUploaded, - bool bMustRecreateSharedTexture= false) = 0; + virtual bool setupTextureEx( ITexture &tex, bool bUpload, bool &bAllUploaded, + bool bMustRecreateSharedTexture = false) = 0; /** The texture must be created or uploadTexture do nothing. * These function can be used to upload piece by piece a texture. Use it in conjunction with setupTextureEx(..., false); * For compressed textures, the rect must aligned on pixel block. (a block of pixel size is 4x4 pixels). */ - virtual bool uploadTexture (ITexture& tex, NLMISC::CRect& rect, uint8 nNumMipMap) = 0; - virtual bool uploadTextureCube (ITexture& tex, NLMISC::CRect& rect, uint8 nNumMipMap, uint8 nNumFace) = 0; + virtual bool uploadTexture(ITexture &tex, NLMISC::CRect &rect, uint8 nNumMipMap) = 0; + virtual bool uploadTextureCube(ITexture &tex, NLMISC::CRect &rect, uint8 nNumMipMap, uint8 nNumFace) = 0; /** * Invalidate shared texture */ - bool invalidateShareTexture (ITexture &); + bool invalidateShareTexture(ITexture &); /** * Get the driver share texture name */ - static void getTextureShareName (const ITexture& tex, std::string &output); + static void getTextureShareName(const ITexture &tex, std::string &output); /** if true force all the uncompressed RGBA 32 bits and RGBA 24 bits texture to be DXTC5 compressed. * Do this only during upload if ITexture::allowDegradation() is true and if ITexture::UploadFormat is "Automatic" * and if bitmap format is RGBA. */ - virtual void forceDXTCCompression(bool dxtcComp)=0; + virtual void forceDXTCCompression(bool dxtcComp) = 0; /** if different from 0, enable anisotropic filter on textures. -1 enables max value. * Default is 0. */ - virtual void setAnisotropicFilter(sint filter)=0; + virtual void setAnisotropicFilter(sint filter) = 0; /** if !=1, force mostly all the textures (but TextureFonts lightmaps, interfaces etc..) * to be divided by Divisor (2, 4, 8...) * Default is 1. * NB: this is done only on TextureFile */ - virtual void forceTextureResize(uint divisor)=0; + virtual void forceTextureResize(uint divisor) = 0; - /** Sets enforcement of native fragment programs. This is by default enabled. - * - * \param nativeOnly If set to false, fragment programs don't need to be native to stay loaded, - * otherwise (aka if true) they will be purged. + /** Get the number of texture stage available, for multi texturing (Normal material shaders). Valid only after setDisplay(). */ - virtual void forceNativeFragmentPrograms(bool nativeOnly) = 0; + virtual uint getNbTextureStages() const = 0; + /** Get max number of per stage constant that can be used simultaneously. + * This will usually match the number of texture stages, but with a D3D driver, this feature is not available most of the time + * so it is emulated. If pixel shaders are available this will be fully supported. + * 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; + + // [DEPRECATED] Return if this texture is a rectangle texture that requires RECT sampler (OpenGL specific pre-NPOT functionality) + virtual bool isTextureRectangle(ITexture *tex) const = 0; - virtual bool setupMaterial(CMaterial& mat)=0; + // Return true if driver support non-power of two textures + virtual bool supportNonPowerOfTwoTextures() const = 0; + // @} - /** - * Activate a shader, NULL to disable the current shader. - */ - virtual bool activeShader(CShader *shd)=0; + + + /// \name Texture operations + // @{ + // copy the first texture in a second one of different dimensions + virtual bool stretchRect(ITexture *srcText, NLMISC::CRect &srcRect, ITexture *destText, NLMISC::CRect &destRect) = 0; + // @} + + + + /// \name Material + // @{ + virtual bool setupMaterial(CMaterial &mat) = 0; /** Special for Faster Specular Setup. Call this between lot of primitives rendered with Specular Materials. * Visual Errors may arise if you don't correctly call endSpecularBatch(). */ - virtual void startSpecularBatch()=0; - virtual void endSpecularBatch()=0; + virtual void startSpecularBatch() = 0; + virtual void endSpecularBatch() = 0; /// \name Material multipass. /** NB: setupMaterial() must be called before those methods. @@ -335,18 +470,26 @@ public: * NB: Other render calls performs the needed setup automatically */ // @{ - /// init multipass for _CurrentMaterial. return number of pass required to render this material. - virtual sint beginMaterialMultiPass() = 0; - /// active the ith pass of this material. - virtual void setupMaterialPass(uint pass) = 0; - /// end multipass for this material. - virtual void endMaterialMultiPass() = 0; + /// init multipass for _CurrentMaterial. return number of pass required to render this material. + virtual sint beginMaterialMultiPass() = 0; + /// active the ith pass of this material. + virtual void setupMaterialPass(uint pass) = 0; + /// end multipass for this material. + virtual void endMaterialMultiPass() = 0; // @} + // Does the driver support the per-pixel lighting shader ? + virtual bool supportPerPixelLighting(bool specular) const = 0; + // @} + + + + /// \name Camera + // @{ // Setup the camera mode as a perspective/ortho camera. NB: znear and zfar must be >0 (if perspective). - virtual void setFrustum(float left, float right, float bottom, float top, float znear, float zfar, bool perspective=true)=0; - virtual void setFrustumMatrix(CMatrix &frust)=0; - virtual CMatrix getFrustumMatrix()=0; + virtual void setFrustum(float left, float right, float bottom, float top, float znear, float zfar, bool perspective = true) = 0; + virtual void setFrustumMatrix(CMatrix &frust) = 0; + virtual CMatrix getFrustumMatrix() = 0; virtual float getClipSpaceZMin() const = 0; @@ -354,7 +497,7 @@ public: * * NB: you must setupViewMatrix() BEFORE setupModelMatrix(), or else undefined results. */ - virtual void setupViewMatrix(const CMatrix& mtx)=0; + virtual void setupViewMatrix(const CMatrix &mtx)=0; /** setup the view matrix (inverse of camera matrix). * Extended: give a cameraPos (mtx.Pos() is not taken into account but for getViewMatrix()), @@ -368,38 +511,40 @@ public: * \param mtx the same view matrix (still with correct "inversed" camera position) as if passed in setupViewMatrix() * \param cameraPos position of the camera (before inversion, ie mtx.getPos()!=cameraPos ). */ - virtual void setupViewMatrixEx(const CMatrix& mtx, const CVector &cameraPos)=0; + virtual void setupViewMatrixEx(const CMatrix &mtx, const CVector &cameraPos) = 0; /** setup the model matrix. * * NB: you must setupModelMatrix() AFTER setupViewMatrix(), or else undefined results. */ - virtual void setupModelMatrix(const CMatrix& mtx)=0; + virtual void setupModelMatrix(const CMatrix &mtx) = 0; + + virtual CMatrix getViewMatrix() const = 0; + // @} - virtual CMatrix getViewMatrix(void)const=0; + /// \name Fixed pipeline vertex program + // @{ /** Force input normal to be normalized by the driver. default is false. * NB: driver force the normalization himself if: * - current Model matrix has a scale. */ - virtual void forceNormalize(bool normalize)=0; + virtual void forceNormalize(bool normalize) = 0; /** return the forceNormalize() state. */ - virtual bool isForceNormalize() const =0; + virtual bool isForceNormalize() const = 0; + // @} + - /** Get max number of per stage constant that can be used simultaneously. - * This will usually match the number of texture stages, but with a D3D driver, this feature is not available most of the time - * so it is emulated. If pixel shaders are available this will be fully supported. - */ - virtual void getNumPerStageConstant(uint &lightedMaterial, uint &unlightedMaterial) const = 0; - + /// \name Vertex Buffer Hard: Features + // @{ /** return true if driver support VertexBufferHard. */ - virtual bool supportVertexBufferHard() const =0; + virtual bool supportVertexBufferHard() const = 0; /** return true if volatile vertex buffer are supported. (e.g a vertex buffer which can be created with the flag CVertexBuffer::AGPVolatile or CVertexBuffer::RAMVolatile) * If these are not supported, a RAM vb is created instead (transparent to user) @@ -413,9 +558,13 @@ public: /** return true if driver support VertexBufferHard, but vbHard->unlock() are slow (ATI-openGL). */ - virtual bool slowUnlockVertexBufferHard() const =0; + virtual bool slowUnlockVertexBufferHard() const = 0; + // @} + + /// \name Vertex Buffer Hard: Settings + // @{ /* Returns true if static vertex and index buffers must by allocated in VRAM, false in AGP. * Default is false. */ @@ -426,16 +575,15 @@ public: */ void setStaticMemoryToVRAM(bool staticMemoryToVRAM); - /** Return the driver reset counter. - * The reset counter is incremented at each driver reset. - */ - uint getResetCounter () const { return _ResetCounter; } - /** return How many vertices VertexBufferHard support */ - virtual uint getMaxVerticesByVertexBufferHard() const =0; + virtual uint getMaxVerticesByVertexBufferHard() const = 0; + // @} + + /// \name Vertex Buffer Hard + // @{ /** Allocate the initial VertexArray Memory. (no-op if !supportVertexBufferHard()). * VertexArrayRange is first reseted, so any VBhard created before will be deleted. * NB: call it after setDisplay(). But setDisplay() by default call initVertexBufferHard(16Mo, 0); @@ -445,17 +593,21 @@ public: * \param vramMem amount of VRAM Memory required. if 0, reseted. * \return false if one the Buffer has not been allocated (at least at 500K). */ - virtual bool initVertexBufferHard(uint agpMem, uint vramMem=0) =0; + virtual bool initVertexBufferHard(uint agpMem, uint vramMem = 0) = 0; /** Return the amount of AGP memory allocated by initVertexBufferHard() to store vertices. */ - virtual uint32 getAvailableVertexAGPMemory () =0; + virtual uint32 getAvailableVertexAGPMemory() = 0; /** Return the amount of video memory allocated by initVertexBufferHard() to store vertices. */ - virtual uint32 getAvailableVertexVRAMMemory () =0; + virtual uint32 getAvailableVertexVRAMMemory() = 0; + // @} + + /// \name Vertex Buffer Objects + // @{ /** active a current VB, for future render(). * This method suppose that all vertices in the VB will be used. * @@ -465,29 +617,33 @@ public: * * \see activeVertexProgram */ - virtual bool activeVertexBuffer(CVertexBuffer& VB)=0; + virtual bool activeVertexBuffer(CVertexBuffer &VB) = 0; /** active a current IB, for future render(). * * Don't change the index buffer format/size after having activated it. * Don't lock the index buffer after having activated it. */ - virtual bool activeIndexBuffer(CIndexBuffer& IB)=0; + virtual bool activeIndexBuffer(CIndexBuffer &IB) = 0; + // @} + + /// \name Rendering + // @{ /** Render a list of indexed lines with previously setuped VertexBuffer / IndexBuffer / Matrixes. * \param mat is the material to use during this rendering * \param firstIndex is the first index in the index buffer to use as first line. * \param nlines is the number of line to render. */ - virtual bool renderLines(CMaterial& mat, uint32 firstIndex, uint32 nlines)=0; + virtual bool renderLines(CMaterial &mat, uint32 firstIndex, uint32 nlines) = 0; /** Render a list of indexed triangles with previously setuped VertexBuffer / IndexBuffer / Matrixes. * \param mat is the material to use during this rendering * \param firstIndex is the first index in the index buffer to use as first triangle. * \param ntris is the number of triangle to render. */ - virtual bool renderTriangles(CMaterial& mat, uint32 firstIndex, uint32 ntris)=0; + virtual bool renderTriangles(CMaterial &mat, uint32 firstIndex, uint32 ntris) = 0; /** Render a list of triangles with previously setuped VertexBuffer / IndexBuffer / Matrixes, AND previously setuped MATERIAL!! * This use the last material setuped. It should be a "Normal shader" material, because no multi-pass is allowed @@ -498,7 +654,7 @@ public: * \param firstIndex is the first index in the index buffer to use as first triangle. * \param ntris is the number of triangle to render. */ - virtual bool renderSimpleTriangles(uint32 firstIndex, uint32 ntris)=0; + virtual bool renderSimpleTriangles(uint32 firstIndex, uint32 ntris) = 0; /** Render points with previously setuped VertexBuffer / Matrixes. * Points are stored as a sequence in the vertex buffer. @@ -506,7 +662,7 @@ public: * \param startVertex is the first vertex to use during this rendering. * \param numPoints is the number of point to render. */ - virtual bool renderRawPoints(CMaterial& mat, uint32 startVertex, uint32 numPoints)=0; + virtual bool renderRawPoints(CMaterial &mat, uint32 startVertex, uint32 numPoints) = 0; /** Render lines with previously setuped VertexBuffer / Matrixes. * Lines are stored as a sequence in the vertex buffer. @@ -514,7 +670,7 @@ public: * \param startVertex is the first vertex to use during this rendering. * \param numLine is the number of line to render. */ - virtual bool renderRawLines(CMaterial& mat, uint32 startVertex, uint32 numTri)=0; + virtual bool renderRawLines(CMaterial &mat, uint32 startVertex, uint32 numTri) = 0; /** Render triangles with previously setuped VertexBuffer / Matrixes. * Triangles are stored as a sequence in the vertex buffer. @@ -522,16 +678,15 @@ public: * \param startVertex is the first vertex to use during this rendering. * \param numTri is the number of triangle to render. */ - virtual bool renderRawTriangles(CMaterial& mat, uint32 startVertex, uint32 numTri)=0; - virtual bool renderRawTriangles2( CMaterial &mat, uint32 startVertex, uint32 numTri ){ return false; } + virtual bool renderRawTriangles(CMaterial &mat, uint32 startVertex, uint32 numTri) = 0; /** If the driver support it, primitive can be rendered with an offset added to each index * These are the offseted version of the 'render' functions * \see supportIndexOffset */ - virtual bool renderLinesWithIndexOffset(CMaterial& mat, uint32 firstIndex, uint32 nlines, uint indexOffset)=0; - virtual bool renderTrianglesWithIndexOffset(CMaterial& mat, uint32 firstIndex, uint32 ntris, uint indexOffset)=0; - virtual bool renderSimpleTrianglesWithIndexOffset(uint32 firstIndex, uint32 ntris, uint indexOffset)=0; + virtual bool renderLinesWithIndexOffset(CMaterial &mat, uint32 firstIndex, uint32 nlines, uint indexOffset) = 0; + virtual bool renderTrianglesWithIndexOffset(CMaterial &mat, uint32 firstIndex, uint32 ntris, uint indexOffset) = 0; + virtual bool renderSimpleTrianglesWithIndexOffset(uint32 firstIndex, uint32 ntris, uint indexOffset) = 0; /** render quads with previously setuped VertexBuffer / Matrixes. @@ -548,8 +703,13 @@ public: * \param startVertex is the first vertex to use during this rendering. * \param numQuad is the number of quad to render. */ - virtual bool renderRawQuads(CMaterial& mat, uint32 startVertex, uint32 numQuads)=0; + virtual bool renderRawQuads(CMaterial &mat, uint32 startVertex, uint32 numQuads) = 0; + // @} + + + /// \name Texture coordinates fixed pipeline + // @{ /** Say what Texture Stage use what UV coord. * by default activeVertexBuffer*() methods map all stage i to UV i. You can change this behavior, * after calling activeVertexBuffer*(), by using this method. @@ -561,63 +721,58 @@ public: * Warning!: some CMaterial Shader may change automatically this behavior too when setupMaterial() * (and so render*()) is called. But Normal shader doesn't do it. */ - virtual void mapTextureStageToUV(uint stage, uint uv)=0; + virtual void mapTextureStageToUV(uint stage, uint uv) = 0; + // @} - /// Swap the back and front buffers. - virtual bool swapBuffers(void)=0; - /// Copy a string to system clipboard. - virtual bool copyTextToClipboard(const ucstring &text) =0; - /// Paste a string from system clipboard. - virtual bool pasteTextFromClipboard(ucstring &text) =0; + /// \name Buffer swapping + // @{ + /// Swap the back and front buffers. + virtual bool swapBuffers() = 0; /** set the number of VBL wait when a swapBuffers() is issued. 0 means no synchronisation to the VBL * Default is 1. Values >1 may be clamped to 1 by the driver. */ - virtual void setSwapVBLInterval(uint interval)=0; + virtual void setSwapVBLInterval(uint interval) = 0; /// get the number of VBL wait when a swapBuffers() is issued. 0 means no synchronisation to the VBL - virtual uint getSwapVBLInterval()=0; + virtual uint getSwapVBLInterval() = 0; + // @} + - /// \name Profiling. - // @{ + /// \name Profiling. + // @{ /** Get the number of primitives rendered from the last swapBuffers() call. * \param pIn the number of requested rendered primitive. * \param pOut the number of effective rendered primitive. pOut==pIn if no multi-pass material is used * (Lightmap, Specular ...). */ - virtual void profileRenderedPrimitives(CPrimitiveProfile &pIn, CPrimitiveProfile &pOut) =0; - + virtual void profileRenderedPrimitives(CPrimitiveProfile &pIn, CPrimitiveProfile &pOut) = 0; /** Return the amount of Texture memory requested. taking mipmap, compression, texture format, etc... into account. * NB: because of GeForce*, RGB888 is considered to be 32 bits. So it may be false for others cards :). */ - virtual uint32 profileAllocatedTextureMemory() =0; - + virtual uint32 profileAllocatedTextureMemory() = 0; /** Get the number of material setuped from the last swapBuffers() call. */ - virtual uint32 profileSetupedMaterials() const =0; - + virtual uint32 profileSetupedMaterials() const = 0; /** Get the number of matrix setuped from the last swapBuffers() call. */ - virtual uint32 profileSetupedModelMatrix() const =0; - + virtual uint32 profileSetupedModelMatrix() const = 0; /** Enable the sum of texture memory used since last swapBuffers() call. To retrieve the memory used call getUsedTextureMemory(). */ - virtual void enableUsedTextureMemorySum (bool enable=true) =0; - + virtual void enableUsedTextureMemorySum (bool enable = true) = 0; /** Return the amount of texture video memory used since last swapBuffers() call. Before use this method, you should enable * the sum with enableUsedTextureMemorySum(). */ - virtual uint32 getUsedTextureMemory() const =0; - + virtual uint32 getUsedTextureMemory() const = 0; /** If the driver support it, enable profile VBHard locks. * No-Op if already profiling @@ -646,179 +801,126 @@ public: /** For each texture setuped in the driver, "print" result: type, shareName, format and size (mipmap included) */ void profileTextureUsage(std::vector &result); - // @} + /// \name Fog support. // @{ - virtual bool fogEnabled()=0; - virtual void enableFog(bool enable)=0; + virtual bool fogEnabled() = 0; + virtual void enableFog(bool enable = true) = 0; /// setup fog parameters. fog must enabled to see result. start and end are distance values. - virtual void setupFog(float start, float end, CRGBA color)=0; + virtual void setupFog(float start, float end, NLMISC::CRGBA color) = 0; /// Get. - virtual float getFogStart() const =0; - virtual float getFogEnd() const =0; - virtual CRGBA getFogColor() const =0; + virtual float getFogStart() const = 0; + virtual float getFogEnd() const = 0; + virtual NLMISC::CRGBA getFogColor() const = 0; // @} - /// Deriver should calls IDriver::release() first, to destroy all driver components (textures, shaders, VBuffers). - virtual bool release(void); - - /// Return true if driver is still active. Return false else. If he user close the window, must return false. - virtual bool isActive()=0; - /// Return the depth of the driver after init(). - virtual uint8 getBitPerPixel ()=0; - - /** Output a system message box and print a message with an icon. This method can be call even if the driver is not initialized. - * This method is used to return internal driver problem when string can't be displayed in the driver window. - * If the driver can't open a messageBox, it should not override this method and let the IDriver class manage it with the ASCII console. - * - * \param message This is the message to display in the message box. - * \param title This is the title of the message box. - * \param type This is the type of the message box, ie number of button and label of buttons. - * \param icon This is the icon of the message box should use like warning, error etc... - */ - virtual TMessageBoxId systemMessageBox (const char* message, const char* title, TMessageBoxType type=okType, TMessageBoxIcon icon=noIcon); + /// \name Viewport + // @{ /** Set the current viewport * * \param viewport is a viewport to setup as current viewport. */ - virtual void setupViewport (const class CViewport& viewport)=0; + virtual void setupViewport(const class CViewport &viewport) = 0; /** Get the current viewport */ virtual void getViewport(CViewport &viewport) = 0; - /** Set the current Scissor. * \param scissor is a scissor to setup the current Scissor, in Window relative coordinate (0,1). */ - virtual void setupScissor (const class CScissor& scissor)=0; + virtual void setupScissor(const class CScissor &scissor) = 0; + // @} + + /// \name Driver information + // @{ /** * Get the driver version. Not the same than interface version. Incremented at each implementation change. * * \see InterfaceVersion */ - virtual uint32 getImplementationVersion () const = 0; + virtual uint32 getImplementationVersion() const = 0; /** * Get driver information. * get the nel name of the driver (ex: "Opengl 1.2 NeL Driver") */ - virtual const char* getDriverInformation () = 0; + virtual const char *getDriverInformation() = 0; /** * Get videocard information. * get the official name of the driver */ - virtual const char* getVideocardInformation () = 0; - - /// \name Mouse / Keyboard / Game devices - // @{ - /// show cursor if b is true, or hide it if b is false - virtual void showCursor (bool b) = 0; - - /// x and y must be between 0.0 and 1.0 - virtual void setMousePos (float x, float y) = 0; - - /** Enable / disable low level mouse. This allow to take advantage of some options (speed of the mouse, automatic wrapping) - * It returns a interface to these parameters when it is supported, or NULL otherwise - * The interface pointer is valid as long as the low level mouse is enabled. - * A call to disable the mouse returns NULL, and restore the default mouse behavior - * NB : - In this mode the mouse cursor isn't drawn. - * - Calls to showCursor have no effects - * - Calls to setCapture have no effects - */ - virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive) = 0; - - /** Enable / disable a low level keyboard. - * Such a keyboard can only send KeyDown and KeyUp event. It just consider the keyboard as a - * gamepad with lots of buttons... - * This returns a interface to some parameters when it is supported, or NULL otherwise. - * The interface pointer is valid as long as the low level keyboard is enabled. - * A call to disable the keyboard returns NULL, and restore the default keyboard behavior - */ - virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable) = 0; - - /** Get the delay in ms for mouse double clicks. - */ - virtual uint getDoubleClickDelay(bool hardwareMouse) = 0; - - /** If true, capture the mouse to force it to stay under the window. - * NB : this has no effects if a low level mouse is used - */ - virtual void setCapture (bool b) = 0; - - // see if system cursor is currently captured - virtual bool isSystemCursorCaptured() = 0; - - // Add a new cursor (name is case unsensitive) - virtual void addCursor(const std::string &name, const NLMISC::CBitmap &bitmap) = 0; - - // Display a cursor from its name (case unsensitive) - virtual void setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild = false) = 0; - - // Change default scale for all cursors - virtual void setCursorScale(float scale) = 0; - - /** Check whether there is a low level device manager available, and get its interface. Return NULL if not available - * From this interface you can deal with mouse and keyboard as above, but you can also manage game device (joysticks, joypads ...) - */ - virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager() = 0; + virtual const char *getVideocardInformation () = 0; // @} - /// Get the width and the height of the window - virtual void getWindowSize (uint32 &width, uint32 &height) = 0; - /// Get the position of the window always (0,0) in fullscreen - virtual void getWindowPos (sint32 &x, sint32 &y) = 0; - /** get the RGBA back buffer. After swapBuffers(), the content of the back buffer is undefined. - * - * \param bitmap the buffer will be written in this bitmap + /// \name Mouse / Keyboard / Game devices + // @{ + /// show cursor if b is true, or hide it if b is false + virtual void showCursor(bool b) = 0; + + /// x and y must be between 0.0 and 1.0 + virtual void setMousePos(float x, float y) = 0; + + /** Enable / disable low level mouse. This allow to take advantage of some options (speed of the mouse, automatic wrapping) + * It returns a interface to these parameters when it is supported, or NULL otherwise + * The interface pointer is valid as long as the low level mouse is enabled. + * A call to disable the mouse returns NULL, and restore the default mouse behavior + * NB : - In this mode the mouse cursor isn't drawn. + * - Calls to showCursor have no effects + * - Calls to setCapture have no effects + */ + virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive) = 0; + + /** Enable / disable a low level keyboard. + * Such a keyboard can only send KeyDown and KeyUp event. It just consider the keyboard as a + * gamepad with lots of buttons... + * This returns a interface to some parameters when it is supported, or NULL otherwise. + * The interface pointer is valid as long as the low level keyboard is enabled. + * A call to disable the keyboard returns NULL, and restore the default keyboard behavior */ - virtual void getBuffer (CBitmap &bitmap) = 0; + virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable) = 0; - /** get the ZBuffer (back buffer). - * - * \param zbuffer the returned array of Z. size of getWindowSize() . + /** Get the delay in ms for mouse double clicks. */ - virtual void getZBuffer (std::vector &zbuffer) = 0; + virtual uint getDoubleClickDelay(bool hardwareMouse) = 0; - /** get a part of the RGBA back buffer. After swapBuffers(), the content of the back buffer is undefined. - * NB: 0,0 is the bottom left corner of the screen. - * - * \param bitmap the buffer will be written in this bitmap - * \param rect the in/out (wanted/clipped) part of Color buffer to retrieve. + /** If true, capture the mouse to force it to stay under the window. + * NB : this has no effects if a low level mouse is used */ - virtual void getBufferPart (CBitmap &bitmap, NLMISC::CRect &rect) = 0; + virtual void setCapture(bool b) = 0; - // copy the first texture in a second one of different dimensions - virtual bool stretchRect (ITexture * srcText, NLMISC::CRect &srcRect, ITexture * destText, NLMISC::CRect &destRect) = 0; + // see if system cursor is currently captured + virtual bool isSystemCursorCaptured() = 0; - // is this texture a rectangle texture ? - virtual bool isTextureRectangle(ITexture * tex) const = 0; + // Add a new cursor (name is case unsensitive) + virtual void addCursor(const std::string &name, const NLMISC::CBitmap &bitmap) = 0; - // return true if driver support Bloom effect. - virtual bool supportBloomEffect() const =0; + // Display a cursor from its name (case unsensitive) + virtual void setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild = false) = 0; - // return true if driver support non-power of two textures - virtual bool supportNonPowerOfTwoTextures() const =0; + // Change default scale for all cursors + virtual void setCursorScale(float scale) = 0; - /** get a part of the ZBuffer (back buffer). - * NB: 0,0 is the bottom left corner of the screen. - * - * \param zbuffer the returned array of Z. size of rec.Width*rec.Height. - * \param rect the in/out (wanted/clipped) part of ZBuffer to retrieve. + /** Check whether there is a low level device manager available, and get its interface. Return NULL if not available + * From this interface you can deal with mouse and keyboard as above, but you can also manage game device (joysticks, joypads ...) */ - virtual void getZBufferPart (std::vector &zbuffer, NLMISC::CRect &rect) = 0; + virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager() = 0; + // @} + + /// \name Render target // TODO: Handle Color/ZBuffer/Stencil consistently + // @{ /** Set the current render target. * * The render target can be a texture (tex pointer) or the back buffer (tex = NULL). @@ -851,14 +953,22 @@ public: * \param cubaFace the face of the cube to copy texture to. * \return true if the render target has been changed */ - virtual bool setRenderTarget (ITexture *tex, - uint32 x = 0, - uint32 y = 0, - uint32 width = 0, - uint32 height = 0, - uint32 mipmapLevel = 0, - uint32 cubeFace = 0 - ) = 0 ; + virtual bool setRenderTarget( ITexture *tex, + uint32 x = 0, + uint32 y = 0, + uint32 width = 0, + uint32 height = 0, + uint32 mipmapLevel = 0, + uint32 cubeFace = 0 + ) = 0; + + virtual ITexture *getRenderTarget() const = 0; + + /** Retrieve the render target size. + * If the render target is the frame buffer, it returns the size of the frame buffer. + * It the render target is a texture, it returns the size of the texture mipmap selected as render target. + */ + virtual bool getRenderTargetSize (uint32 &width, uint32 &height) = 0; /** Trick method : copy the current texture target into another texture without updating the current texture. * @@ -886,30 +996,21 @@ public: * \param height height of the renderable area to copy, if 0, use the whole size. * \param mipmapLevel the mipmap to copy texture to. */ - virtual bool copyTargetToTexture (ITexture *tex, - uint32 offsetx = 0, - uint32 offsety = 0, - uint32 x = 0, - uint32 y = 0, - uint32 width = 0, - uint32 height = 0, - uint32 mipmapLevel = 0 + virtual bool copyTargetToTexture( ITexture *tex, + uint32 offsetx = 0, + uint32 offsety = 0, + uint32 x = 0, + uint32 y = 0, + uint32 width = 0, + uint32 height = 0, + uint32 mipmapLevel = 0 ) = 0; + // @} - /** Retrieve the render target size. - * If the render target is the frame buffer, it returns the size of the frame buffer. - * It the render target is a texture, it returns the size of the texture mipmap selected as render target. - */ - virtual bool getRenderTargetSize (uint32 &width, uint32 &height) = 0; - - /** fill the RGBA back buffer - * - * \param bitmap will be written in the buffer. no-op if bad size. - * \return true if success - */ - virtual bool fillBuffer (CBitmap &bitmap) = 0; + /// \name Render state: Polygon mode + // @{ /** Set the global polygon mode. Can be filled, line or point. The implementation driver must * call IDriver::setPolygonMode and active this mode. * @@ -921,13 +1022,27 @@ public: _PolygonMode=mode; } + /** Get the global polygon mode. + * + * \param polygon mode choose in this driver. + * \see setPolygonMode(), TPolygonMode + */ + TPolygonMode getPolygonMode () + { + return _PolygonMode; + } + // @} + + + /// \name Fixed pipeline lights + // @{ /** * return the number of light supported by driver. typically 8. * * \see enableLight() setLight() */ - virtual uint getMaxLight () const = 0; + virtual uint getMaxLight() const = 0; /** * Setup a light. @@ -938,7 +1053,7 @@ public: * \param light is a light to set in this slot. * \see enableLight() */ - virtual void setLight (uint8 num, const CLight& light) = 0; + virtual void setLight(uint8 num, const CLight &light) = 0; /** * Enable / disable light. @@ -949,7 +1064,7 @@ public: * \param enable is true to enable the light, false to disable it. * \see setLight() */ - virtual void enableLight (uint8 num, bool enable=true) = 0; + virtual void enableLight(uint8 num, bool enable = true) = 0; /** * Set ambient. @@ -957,129 +1072,135 @@ public: * \param color is the new global ambient color for the scene. * \see setLight(), enableLight() */ - virtual void setAmbientColor (CRGBA color) = 0; + virtual void setAmbientColor(NLMISC::CRGBA color) = 0; /** Setup the light used for per pixel lighting. The given values should have been modulated by the material diffuse and specular. * This is only useful for material that have their shader set as 'PerPixelLighting' * \param the light used for per pixel lighting */ - virtual void setPerPixelLightingLight(CRGBA diffuse, CRGBA specular, float shininess) = 0; + virtual void setPerPixelLightingLight(NLMISC::CRGBA diffuse, NLMISC::CRGBA specular, float shininess) = 0; /** Setup the unique light used for Lightmap Shader. * Lightmaped primitives are lit per vertex with this light (should be local attenuated for maximum efficiency) * This is only useful for material that have their shader set as 'LightMap' * \param the light used for per pixel lighting */ - virtual void setLightMapDynamicLight (bool enable, const CLight& light) = 0; - - /** Get the global polygon mode. - * - * \param polygon mode choose in this driver. - * \see setPolygonMode(), TPolygonMode - */ - TPolygonMode getPolygonMode () - { - return _PolygonMode; - } + virtual void setLightMapDynamicLight(bool enable, const CLight &light) = 0; + // @} - /// \name Vertex program interface - // @{ - enum TMatrix - { - ModelView= 0, - Projection, - ModelViewProjection, - NumMatrix - }; - enum TTransform - { - Identity=0, - Inverse, - Transpose, - InverseTranspose, - NumTransform - }; + /// \name Vertex Program + // @{ - /** - * Does the driver supports vertex programs ? - */ - virtual bool isVertexProgramSupported () const =0; + // Order of preference + // - activeVertexProgram + // - CMaterial pass[n] VP (uses activeVertexProgram, but does not override if one already set by code) + // - default generic VP that mimics fixed pipeline / no VP with fixed pipeline /** * Does the driver supports vertex program, but emulated by CPU ? */ - virtual bool isVertexProgramEmulated () const =0; + virtual bool isVertexProgramEmulated() const = 0; + /** Return true if the driver supports the specified vertex program profile. + */ + virtual bool supportVertexProgram(CVertexProgram::TProfile profile) const = 0; + /** Compile the given vertex program, return if successful. + * If a vertex program was set active before compilation, + * the state of the active vertex program is undefined behaviour afterwards. + */ + virtual bool compileVertexProgram(CVertexProgram *program) = 0; - /** - * Activate / disactivate a vertex program - * - * \param program is a pointer on a vertex program. Can be NULL to disable the current vertex program. - * - * \return true if setup/unsetup succeeded, false else. + /** Set the active vertex program. This will override vertex programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getVertexProgram returns NULL. + * The vertex program is activated immediately. */ - virtual bool activeVertexProgram (CVertexProgram *program) =0; + virtual bool activeVertexProgram(CVertexProgram *program) = 0; + // @} - /// Activates the specified GPU program object - virtual bool activeProgramObject( IProgramObject *program ){ return false; }; - /// Creates a new GPU program object - virtual IProgramObject* createProgramObject() const { return NULL; } + /// \name Pixel Program + // @{ - /// Creates a new Vertex program - virtual IProgram* createVertexProgram() const { return NULL; } + // Order of preference + // - activePixelProgram + // - CMaterial pass[n] PP (uses activePixelProgram, but does not override if one already set by code) + // - PP generated from CMaterial (uses activePixelProgram, but does not override if one already set by code) - /// Creates a new Pixel program - virtual IProgram* createPixelProgram() const { return NULL; } + /** Return true if the driver supports the specified pixel program profile. + */ + virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const = 0; - /// Returns the location of the specified uniform in the specified program type ( vertex, pixel, etc ), or -1 if it's not found - virtual int getUniformLocation( uint32 programType, const char *name ){ return -1; } + /** Compile the given pixel program, return if successful. + * If a pixel program was set active before compilation, + * the state of the active pixel program is undefined behaviour afterwards. + */ + virtual bool compilePixelProgram(CPixelProgram *program) = 0; - /// Sets a single float uniform - virtual void setUniform1f( uint32 programType, uint index, float f ){} + /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getPixelProgram returns NULL. + * The pixel program is activated immediately. + */ + virtual bool activePixelProgram(CPixelProgram *program) = 0; + // @} - /// Sets 4 floats uniform value ( vector ) - virtual void setUniform4f( uint32 programType, uint index, float f1, float f2, float f3, float f4 ){} - /// Sets a single integer uniform value - virtual void setUniform1i( uint32 programType, uint index, int i ){} - /// Sets a 4 integer uniform value ( vector ) - virtual void setUniform4i( uint32 programType, uint index, int i1, int i2, int i3, int i4 ){} + /// \name Geometry Program + // @{ - /// Sets a single unsigned integer uniform value - virtual void setUniform1u( uint32 programType, uint index, uint u ){} + // Order of preference + // - activeGeometryProgram + // - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code) + // - none - /// Sets a 4 unsigned integer uniform value - virtual void setUniform4u( uint32 programType, uint index, uint u1, uint u2, uint u3, uint u4 ){} + /** Return true if the driver supports the specified pixel program profile. + */ + virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const = 0; - /// Sets a 2x2 float matrix uniform value ( column major order ) - virtual void setUniformMatrix2fv( uint32 programType, uint index, uint count, bool transpose, const float *values ){} + /** Compile the given pixel program, return if successful. + * If a pixel program was set active before compilation, + * the state of the active pixel program is undefined behaviour afterwards. + */ + virtual bool compileGeometryProgram(CGeometryProgram *program) = 0; - /// Sets a 3x3 float matrix uniform value ( column major order ) - virtual void setUniformMatrix3fv( uint32 programType, uint index, uint count, bool transpose, const float *values ){} + /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getGeometryProgram returns NULL. + * The pixel program is activated immediately. + */ + virtual bool activeGeometryProgram(CGeometryProgram *program) = 0; + // @} - /// Sets a 4x4 float matrix uniform value ( column major order ) - virtual void setUniformMatrix4fv( uint32 programType, uint index, uint count, bool transpose, const float *values ){} - /** - * Setup constant values. - */ - virtual void setConstant (uint index, float, float, float, float) =0; - virtual void setConstant (uint index, double, double, double, double) =0; - virtual void setConstant (uint index, const NLMISC::CVector& value) =0; - virtual void setConstant (uint index, const NLMISC::CVectorD& value) =0; - /// setup several 4 float csts taken from the given tab - virtual void setConstant (uint index, uint num, const float *src) =0; - /// setup several 4 double csts taken from the given tab - virtual void setConstant (uint index, uint num, const double *src) =0; + /// \name Program parameters + // @{ + // Set parameters + virtual void setUniform1f(TProgram program, uint index, float f0) = 0; + virtual void setUniform2f(TProgram program, uint index, float f0, float f1) = 0; + virtual void setUniform3f(TProgram program, uint index, float f0, float f1, float f2) = 0; + virtual void setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3) = 0; + virtual void setUniform1i(TProgram program, uint index, sint32 i0) = 0; + virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1) = 0; + virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2) = 0; + virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) = 0; + virtual void setUniform1ui(TProgram program, uint index, uint32 ui0) = 0; + virtual void setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1) = 0; + virtual void setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2) = 0; + virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) = 0; + virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v) = 0; + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3) = 0; + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba) = 0; + virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) = 0; + virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src) = 0; + virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src) = 0; + virtual void setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src) = 0; + // Set builtin parameters /** - * Setup constants with a current matrix. + * Setup uniforms with a current matrix. * * This call must be done after setFrustum(), setupViewMatrix() or setupModelMatrix() to get correct * results. @@ -1089,10 +1210,9 @@ public: * \param transform is the transformation to apply to the matrix before store it in the constants. * */ - virtual void setConstantMatrix (uint index, TMatrix matrix, TTransform transform) =0; - + virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform) = 0; /** - * Setup the constant with the fog vector. This vector must be used to get the final fog value in a vertex shader. + * Setup the uniform with the fog vector. This vector must be used to get the final fog value in a vertex shader. * You must use it like this: * DP4 o[FOGC].x, c[4], R4; * With c[4] the constant used for the fog vector and R4 the vertex local position. @@ -1103,14 +1223,28 @@ public: * \param index is the index where to store the vector. * */ - virtual void setConstantFog (uint index) =0; + virtual void setUniformFog(TProgram program, uint index) = 0; + // Set feature parameters + virtual bool isUniformProgramState() = 0; + // @} - /// Check if the driver support double sided colors vertex programs - virtual bool supportVertexProgramDoubleSidedColor() const = 0; + + /// \name Legacy effects + // @{ // test if support for cloud render in a single pass virtual bool supportCloudRenderSinglePass() const = 0; + // [FIXME] Return true if driver support Bloom effect // FIXME: This is terrible + virtual bool supportBloomEffect() const = 0; + // @} + + + + /// \name Backface color + // @{ + /// Check if the driver support double sided colors vertex programs + virtual bool supportVertexProgramDoubleSidedColor() const = 0; /** * Activate VertexProgram 2Sided Color mode. In 2Sided mode, the BackFace (if material 2Sided enabled) read the * result from o[BFC0], and not o[COL0]. @@ -1118,27 +1252,29 @@ public: * NB: no-op if not supported by driver */ virtual void enableVertexProgramDoubleSidedColor(bool doubleSided) =0; - // @} + + /// \name Texture addressing modes aka textures/pixels shaders // @{ - /// test whether the device supports some form of texture shader. (could be limited to DX6 EMBM for example) - virtual bool supportTextureShaders() const = 0; - // Is the shader water supported ? If not, the driver caller should implement its own version - virtual bool isWaterShaderSupported() const = 0; - // - /// test whether a texture addressing mode is supported - virtual bool isTextureAddrModeSupported(CMaterial::TTexAddressingMode mode) const = 0; - /** setup the 2D matrix for the OffsetTexture, OffsetTextureScale and OffsetTexture addressing mode - * It should be stored as the following - * [a0 a1] - * [a2 a3] - */ - virtual void setMatrix2DForTextureOffsetAddrMode(const uint stage, const float mat[4]) = 0; + /// test whether the device supports some form of texture shader. (could be limited to DX6 EMBM for example) + virtual bool supportTextureShaders() const = 0; + // Is the shader water supported ? If not, the driver caller should implement its own version + virtual bool supportWaterShader() const = 0; + // + /// test whether a texture addressing mode is supported + virtual bool supportTextureAddrMode(CMaterial::TTexAddressingMode mode) const = 0; + /** setup the 2D matrix for the OffsetTexture, OffsetTextureScale and OffsetTexture addressing mode + * It should be stored as the following + * [a0 a1] + * [a2 a3] + */ + virtual void setMatrix2DForTextureOffsetAddrMode(const uint stage, const float mat[4]) = 0; //@} + /** \name EMBM support. If texture shaders are present, this is not available, must use them instead. * EMBM is a color op of CMaterial. * NB : EMBM is the equivalent of the CMaterial::OffsetTexture addressing mode. However, it is both a texture @@ -1150,38 +1286,35 @@ public: */ // @{ - // Test if EMBM is supported. - virtual bool supportEMBM() const = 0; - // Test if EMBM is supported for the given stage - virtual bool isEMBMSupportedAtStage(uint stage) const = 0; - // set the matrix used for EMBM addressing - virtual void setEMBMMatrix(const uint stage, const float mat[4]) = 0; + // Test if EMBM is supported. + virtual bool supportEMBM() const = 0; + // Test if EMBM is supported for the given stage + virtual bool isEMBMSupportedAtStage(uint stage) const = 0; + // set the matrix used for EMBM addressing + virtual void setEMBMMatrix(const uint stage, const float mat[4]) = 0; // @} - // Does the driver support the per-pixel lighting shader ? - virtual bool supportPerPixelLighting(bool specular) const = 0; /// \name Misc // @{ - /** Does the driver support Blend Constant Color ??? If yes CMaterial::blendConstant* enum can be used * for blend Src ord Dst factor. If no, using these enum will have undefined results. */ - virtual bool supportBlendConstantColor() const =0; + virtual bool supportBlendConstantColor() const = 0; /** see supportBlendConstantColor(). Set the current Blend Constant Color. */ - virtual void setBlendConstantColor(NLMISC::CRGBA col)=0; + virtual void setBlendConstantColor(NLMISC::CRGBA col) = 0; /** see supportBlendConstantColor(). Get the current Blend Constant Color. */ - virtual NLMISC::CRGBA getBlendConstantColor() const =0; + virtual NLMISC::CRGBA getBlendConstantColor() const = 0; /** force the driver to flush all command. glFinish() in opengl. * Interesting only for debug and profiling purpose. */ - virtual void finish() =0; + virtual void finish() = 0; // Flush command queue an immediately returns virtual void flush() = 0; @@ -1190,27 +1323,27 @@ public: * See GL_POLYGON_SMOOTH help, and GL_SRC_ALPHA_SATURATE OpenGL doc (not yet implemented now since * used only for alpha part in ShadowMap gen) */ - virtual void enablePolygonSmoothing(bool smooth) =0; + virtual void enablePolygonSmoothing(bool smooth) = 0; /// see enablePolygonSmoothing() - virtual bool isPolygonSmoothingEnabled() const =0; - + virtual bool isPolygonSmoothingEnabled() const = 0; // @} + /** Special method to internally swap the Driver handle of 2 textures. * USE IT WITH CARE (eg: may have Size problems, mipmap problems, format problems ...) * Actually, it is used only by CAsyncTextureManager, to manage Lods of DXTC CTextureFile. * NB: internally, all textures slots are disabled. */ - virtual void swapTextureHandle(ITexture &tex0, ITexture &tex1) =0; + virtual void swapTextureHandle(ITexture &tex0, ITexture &tex1) = 0; /** Advanced usage. Get the texture Handle.Useful for texture sorting for instance * NB: if the texture is not setuped in the driver, 0 is returned. * NB: if implementation does not support it, 0 may be returned. OpenGL ones return the Texture ID. * NB: unlike isTextureExist(), this method is not thread safe. */ - virtual uint getTextureHandle(const ITexture&tex)=0; + virtual uint getTextureHandle(const ITexture&tex) = 0; // see if the Multiply-Add Tex Env operator is supported (see CMaterial::Mad) virtual bool supportMADOperator() const = 0; @@ -1231,16 +1364,16 @@ public: }; // Get the number of hardware renderer available on the client platform. - virtual uint getNumAdapter() const=0; + virtual uint getNumAdapter() const = 0; // Get a hardware renderer description. - virtual bool getAdapter(uint adapter, CAdapter &desc) const=0; + virtual bool getAdapter(uint adapter, CAdapter &desc) const = 0; /** Choose the hardware renderer. * Call it before the setDisplay and enumModes methods * Choose adapter = 0xffffffff for the default one. */ - 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) * BGRA : @@ -1254,20 +1387,22 @@ public: */ virtual CVertexBuffer::TVertexColorType getVertexColorFormat() const =0; + + /// \name Bench // @{ - // Start the bench. See CHTimer::startBench(); - virtual void startBench (bool wantStandardDeviation = false, bool quick = false, bool reset = true) =0; + virtual void startBench(bool wantStandardDeviation = false, bool quick = false, bool reset = true) =0; // End the bench. See CHTimer::endBench(); - virtual void endBench () =0; + virtual void endBench () =0; // Display the bench result - virtual void displayBench (class NLMISC::CLog *log) =0; - + virtual void displayBench (class NLMISC::CLog *log) =0; // @} + + /// \name Occlusion query mechanism // @{ // Test whether this device supports the occlusion query mechanism @@ -1280,8 +1415,8 @@ public: virtual void deleteOcclusionQuery(IOcclusionQuery *oq) = 0; // @} - // get the number of call to swapBuffer since the driver was created - virtual uint64 getSwapBufferCounter() const = 0; + + /** Set cull mode * Useful for mirrors / cube map rendering or when the scene must be rendered upside down @@ -1298,29 +1433,29 @@ public: virtual void stencilMask(uint mask) = 0; protected: - friend class IVBDrvInfos; - friend class IIBDrvInfos; - friend class CTextureDrvShare; - friend class ITextureDrvInfos; - friend class IMaterialDrvInfos; - friend class IVertexProgramDrvInfos; - friend class IShaderDrvInfos; + friend class IVBDrvInfos; + friend class IIBDrvInfos; + friend class CTextureDrvShare; + friend class ITextureDrvInfos; + friend class IMaterialDrvInfos; + friend class IProgramDrvInfos; + friend class IProgramParamsDrvInfos; /// remove ptr from the lists in the driver. - void removeVBDrvInfoPtr(ItVBDrvInfoPtrList vbDrvInfoIt); - void removeIBDrvInfoPtr(ItIBDrvInfoPtrList ibDrvInfoIt); - void removeTextureDrvInfoPtr(ItTexDrvInfoPtrMap texDrvInfoIt); - void removeTextureDrvSharePtr(ItTexDrvSharePtrList texDrvShareIt); - void removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt); - void removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt); - void removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt); + void removeVBDrvInfoPtr(ItVBDrvInfoPtrList vbDrvInfoIt); + void removeIBDrvInfoPtr(ItIBDrvInfoPtrList ibDrvInfoIt); + void removeTextureDrvInfoPtr(ItTexDrvInfoPtrMap texDrvInfoIt); + void removeTextureDrvSharePtr(ItTexDrvSharePtrList texDrvShareIt); + void removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt); + void removeGPUPrgDrvInfoPtr(ItGPUPrgDrvInfoPtrList gpuPrgDrvInfoIt); private: - bool _StaticMemoryToVRAM; + bool _StaticMemoryToVRAM; public: /// Reloads the user shaders virtual void reloadUserShaders(){} + }; // -------------------------------------------------- diff --git a/code/nel/include/nel/3d/driver_user.h b/code/nel/include/nel/3d/driver_user.h index bfe4c1755..30ea98c65 100644 --- a/code/nel/include/nel/3d/driver_user.h +++ b/code/nel/include/nel/3d/driver_user.h @@ -133,6 +133,7 @@ public: // @{ virtual void disableHardwareVertexProgram(); + virtual void disableHardwarePixelProgram(); virtual void disableHardwareVertexArrayAGP(); virtual void disableHardwareTextureShader(); @@ -473,7 +474,6 @@ public: virtual void forceDXTCCompression(bool dxtcComp); virtual void setAnisotropicFilter(sint filter); virtual void forceTextureResize(uint divisor); - virtual void forceNativeFragmentPrograms(bool nativeOnly); virtual bool setMonitorColorProperties (const CMonitorColorProperties &properties); // @} diff --git a/code/nel/include/nel/3d/geometry_program.h b/code/nel/include/nel/3d/geometry_program.h new file mode 100644 index 000000000..48e48e260 --- /dev/null +++ b/code/nel/include/nel/3d/geometry_program.h @@ -0,0 +1,49 @@ +/** \file geometry_program.h + * Geometry program definition + */ + +/* Copyright, 2000, 2001 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. + */ + +#ifndef NL_GEOMETRY_PROGRAM_H +#define NL_GEOMETRY_PROGRAM_H + +#include +#include +#include + +#include + +namespace NL3D { + +class CGeometryProgram : public IProgram +{ +public: + /// Constructor + CGeometryProgram(); + /// Destructor + virtual ~CGeometryProgram (); +}; + +} // NL3D + + +#endif // NL_GEOMETRY_PROGRAM_H + +/* End of vertex_program.h */ diff --git a/code/nel/include/nel/3d/gpu_program_params.h b/code/nel/include/nel/3d/gpu_program_params.h new file mode 100644 index 000000000..ce6b8b2f0 --- /dev/null +++ b/code/nel/include/nel/3d/gpu_program_params.h @@ -0,0 +1,178 @@ +/** + * \file gpu_program_params.h + * \brief CGPUProgramParams + * \date 2013-09-07 22:17GMT + * \author Jan Boon (Kaetemi) + * CGPUProgramParams + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifndef NL3D_GPU_PROGRAM_PARAMS_H +#define NL3D_GPU_PROGRAM_PARAMS_H +#include + +// STL includes +#include +#include + +// NeL includes + +// Project includes + +namespace NLMISC { + class CVector; + class CMatrix; +} + +namespace NL3D { + +/** + * \brief CGPUProgramParams + * \date 2013-09-07 22:17GMT + * \author Jan Boon (Kaetemi) + * A storage for USERCODE-PROVIDED parameters for GPU programs. + * Allows for fast updating and iteration of parameters. + * NOTE TO DRIVER IMPLEMENTORS: DO NOT USE FOR STORING COPIES + * OF HARDCODED DRIVER MATERIAL PARAMETERS OR DRIVER PARAMETERS!!! + * The 4-component alignment that is done in this storage + * class is necessary to simplify support for register-based + * assembly shaders, which require setting per 4 components. + */ +class CGPUProgramParams +{ +public: + enum TType { Float, Int, UInt }; + struct CMeta { uint Index, Size, Count; TType Type; std::string Name; size_t Next, Prev; }; // size is element size, count is nb of elements + +private: + union CVec { float F[4]; sint32 I[4]; uint32 UI[4]; }; + +public: + CGPUProgramParams(); + virtual ~CGPUProgramParams(); + + /// \name User functions + // @{ + // Copy from another params storage + void copy(CGPUProgramParams *params); + + // Set by index, available only when the associated program has been compiled + void set1f(uint index, float f0); + void set2f(uint index, float f0, float f1); + void set3f(uint index, float f0, float f1, float f2); + void set4f(uint index, float f0, float f1, float f2, float f3); + void set1i(uint index, sint32 i0); + void set2i(uint index, sint32 i0, sint32 i1); + void set3i(uint index, sint32 i0, sint32 i1, sint32 i2); + void set4i(uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3); + void set1ui(uint index, uint32 ui0); + void set2ui(uint index, uint32 ui0, uint32 ui1); + void set3ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2); + void set4ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3); + void set3f(uint index, const NLMISC::CVector& v); + void set4f(uint index, const NLMISC::CVector& v, float f3); + void set4x4f(uint index, const NLMISC::CMatrix& m); + void set4fv(uint index, size_t num, const float *src); + void set4iv(uint index, size_t num, const sint32 *src); + void set4uiv(uint index, size_t num, const uint32 *src); + void unset(uint index); + + // Set by name, it is recommended to use index when repeatedly setting an element + void set1f(const std::string &name, float f0); + void set2f(const std::string &name, float f0, float f1); + void set3f(const std::string &name, float f0, float f1, float f2); + void set4f(const std::string &name, float f0, float f1, float f2, float f3); + void set1i(const std::string &name, sint32 i0); + void set2i(const std::string &name, sint32 i0, sint32 i1); + void set3i(const std::string &name, sint32 i0, sint32 i1, sint32 i2); + void set4i(const std::string &name, sint32 i0, sint32 i1, sint32 i2, sint32 i3); + void set1ui(const std::string &name, uint32 ui0); + void set2ui(const std::string &name, uint32 ui0, uint32 ui1); + void set3ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2); + void set4ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3); + void set3f(const std::string &name, const NLMISC::CVector& v); + void set4f(const std::string &name, const NLMISC::CVector& v, float f3); + void set4x4f(const std::string &name, const NLMISC::CMatrix& m); + void set4fv(const std::string &name, size_t num, const float *src); + void set4iv(const std::string &name, size_t num, const sint32 *src); + void set4uiv(const std::string &name, size_t num, const uint32 *src); + void unset(const std::string &name); + // @} + + // Maps the given name to the given index. + // on duplicate entry the data set by name will be prefered, as it can be + // assumed to have been set after the data set by index, and the mapping + // will usually happen while iterating and finding an element with name + // but no known index. + // Unknown index will be set to ~0, unknown name will have an empty string. + void map(uint index, const std::string &name); + + /// \name Internal + // @{ + /// Allocate specified number of components if necessary (internal use only) + size_t allocOffset(uint index, uint size, uint count, TType type); + size_t allocOffset(const std::string &name, uint size, uint count, TType type); + size_t allocOffset(uint size, uint count, TType type); + /// Return offset for specified index + size_t getOffset(uint index) const; + size_t getOffset(const std::string &name) const; + /// Remove by offset + void freeOffset(size_t offset); + // @} + + /// \name Driver and dev tools + // @{ + // Iteration (returns the offsets for access using getFooByOffset) + inline size_t getBegin() const { return m_Meta.size() ? m_First : s_End; } + inline size_t getNext(size_t offset) const { return m_Meta[offset].Next; } + inline size_t getEnd() const { return s_End; } + + // Data access + inline uint getSizeByOffset(size_t offset) const { return m_Meta[offset].Size; } // size of element (4 for float4) + inline uint getCountByOffset(size_t offset) const { return m_Meta[offset].Count; } // number of elements (usually 1) + inline uint getNbComponentsByOffset(size_t offset) const { return m_Meta[offset].Size * m_Meta[offset].Count; } // nb of components (size * count) + inline float *getPtrFByOffset(size_t offset) { return m_Vec[offset].F; } + inline sint32 *getPtrIByOffset(size_t offset) { return m_Vec[offset].I; } + inline uint32 *getPtrUIByOffset(size_t offset) { return m_Vec[offset].UI; } + inline TType getTypeByOffset(size_t offset) const { return m_Meta[offset].Type; } + inline uint getIndexByOffset(size_t offset) const { return m_Meta[offset].Index; } + const std::string &getNameByOffset(size_t offset) const { return m_Meta[offset].Name; }; + // @} + + // Utility + static inline uint getNbRegistersByComponents(uint nbComponents) { return (nbComponents + 3) >> 2; } // vector register per 4 components + +private: + std::vector m_Vec; + std::vector m_Meta; + std::vector m_Map; // map from index to offset + std::map m_MapName; // map from name to offset + size_t m_First; + size_t m_Last; + static const size_t s_End = -1; + +}; /* class CGPUProgramParams */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_GPU_PROGRAM_PARAMS_H */ + +/* end of file */ diff --git a/code/nel/include/nel/3d/i_program.h b/code/nel/include/nel/3d/i_program.h deleted file mode 100644 index 6fbe2c141..000000000 --- a/code/nel/include/nel/3d/i_program.h +++ /dev/null @@ -1,159 +0,0 @@ -// NeL - MMORPG Framework -// 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 . - - -#ifndef I_PROGRAM_H -#define I_PROGRAM_H - -#include - -namespace NL3D -{ - /// Interface class for all NEL GPU ( vertex, pixel, geometry, etc ) programs - class IProgram - { - public: - enum TProgramType - { - INVALID_PROGRAM, - VERTEX_PROGRAM, - PIXEL_PROGRAM, - GEOMETRY_PROGRAM - }; - - enum EUniform - { - MVPMatrix, - MVMatrix, - NormalMatrix, - TexMatrix0, - TexMatrix1, - TexMatrix2, - TexMatrix3, - Constant0, - Constant1, - Constant2, - Constant3, - Diffuse, - Color, - Sampler0, - Sampler1, - Sampler2, - Sampler3, - AlphaTreshold, - FogStart, - FogEnd, - FogColor, - FogDensity, - Light0Dir, - Light1Dir, - Light2Dir, - Light3Dir, - Light4Dir, - Light5Dir, - Light6Dir, - Light7Dir, - Light0ColDiff, - Light1ColDiff, - Light2ColDiff, - Light3ColDiff, - Light4ColDiff, - Light5ColDiff, - Light6ColDiff, - Light7ColDiff, - Light0ColAmb, - Light1ColAmb, - Light2ColAmb, - Light3ColAmb, - Light4ColAmb, - Light5ColAmb, - Light6ColAmb, - Light7ColAmb, - Light0ColSpec, - Light1ColSpec, - Light2ColSpec, - Light3ColSpec, - Light4ColSpec, - Light5ColSpec, - Light6ColSpec, - Light7ColSpec, - Light0Shininess, - Light1Shininess, - Light2Shininess, - Light3Shininess, - Light4Shininess, - Light5Shininess, - Light6Shininess, - Light7Shininess, - Light0Pos, - Light1Pos, - Light2Pos, - Light3Pos, - Light4Pos, - Light5Pos, - Light6Pos, - Light7Pos, - Light0ConstAttn, - Light1ConstAttn, - Light2ConstAttn, - Light3ConstAttn, - Light4ConstAttn, - Light5ConstAttn, - Light6ConstAttn, - Light7ConstAttn, - Light0LinAttn, - Light1LinAttn, - Light2LinAttn, - Light3LinAttn, - Light4LinAttn, - Light5LinAttn, - Light6LinAttn, - Light7LinAttn, - Light0QuadAttn, - Light1QuadAttn, - Light2QuadAttn, - Light3QuadAttn, - Light4QuadAttn, - Light5QuadAttn, - Light6QuadAttn, - Light7QuadAttn, - NUM_UNIFORMS - }; - - IProgram(){ - type = INVALID_PROGRAM; - } - - virtual ~IProgram(){} - - void setSource( const char *source ){ src.assign( source ); } - const std::string& getSource() const{ return src; } - - virtual void cacheUniforms() = 0; - virtual int getUniformIndex( uint32 id ) const = 0; - - TProgramType getType() const{ return type; } - - protected: - std::string src; - static const char *uniformNames[ NUM_UNIFORMS ]; - TProgramType type; - }; -} - -#endif - - diff --git a/code/nel/include/nel/3d/landscapevb_allocator.h b/code/nel/include/nel/3d/landscapevb_allocator.h index d3a081e7b..0e485e990 100644 --- a/code/nel/include/nel/3d/landscapevb_allocator.h +++ b/code/nel/include/nel/3d/landscapevb_allocator.h @@ -21,6 +21,7 @@ #include "nel/misc/smart_ptr.h" #include "nel/3d/tessellation.h" #include "nel/3d/vertex_buffer.h" +#include "nel/3d/vertex_program.h" namespace NL3D @@ -41,6 +42,7 @@ class CVertexProgram; #define NL3D_LANDSCAPE_VPPOS_DELTAPOS (CVertexBuffer::TexCoord3) #define NL3D_LANDSCAPE_VPPOS_ALPHAINFO (CVertexBuffer::TexCoord4) +class CVertexProgramLandscape; // *************************************************************************** /** @@ -107,6 +109,8 @@ public: * Give a vertexProgram Id to activate. Always 0, but 1 For tile Lightmap Pass. */ void activate(uint vpId); + void activateVP(uint vpId); + inline CVertexProgramLandscape *getVP(uint vpId) const { return _VertexProgram[vpId]; } // @} @@ -151,15 +155,35 @@ private: /// \name Vertex Program mgt . // @{ +public: enum {MaxVertexProgram= 2,}; // Vertex Program , NULL if not enabled. - CVertexProgram *_VertexProgram[MaxVertexProgram]; +private: + NLMISC::CSmartPtr _VertexProgram[MaxVertexProgram]; void deleteVertexProgram(); void setupVBFormatAndVertexProgram(bool withVertexProgram); // @} }; +class CVertexProgramLandscape : public CVertexProgram +{ +public: + struct CIdx + { + uint ProgramConstants0; + uint RefineCenter; + uint TileDist; + uint PZBModelPosition; + }; + CVertexProgramLandscape(CLandscapeVBAllocator::TType type, bool lightMap = false); + virtual ~CVertexProgramLandscape() { } + virtual void buildInfo(); +public: + const CIdx &idx() const { return m_Idx; } + CIdx m_Idx; +}; + } // NL3D diff --git a/code/nel/include/nel/3d/material.h b/code/nel/include/nel/3d/material.h index 97759ef58..03faf477c 100644 --- a/code/nel/include/nel/3d/material.h +++ b/code/nel/include/nel/3d/material.h @@ -22,7 +22,6 @@ #include "nel/misc/rgba.h" #include "nel/misc/matrix.h" #include "nel/3d/texture.h" -#include "nel/3d/shader.h" #include @@ -173,7 +172,8 @@ public: * - Alpha of texture in stage 0 is blended with alpha of texture in stage 1. Blend done with the alpha color of each * stage and the whole is multiplied by the alpha in color vertex [AT0*ADiffuseCol+AT1*(1-ADiffuseCol)]*AStage * - RGB still unchanged - * + * Water : + * - Water */ enum TShader { Normal=0, Bump, @@ -185,7 +185,8 @@ public: PerPixelLightingNoSpec, Cloud, Water, - shaderCount}; + shaderCount, + Program /* internally used when a pixel program is active */ }; /// \name Texture Env Modes. // @{ diff --git a/code/nel/include/nel/3d/meshvp_per_pixel_light.h b/code/nel/include/nel/3d/meshvp_per_pixel_light.h index d7be0f3f9..a234feddd 100644 --- a/code/nel/include/nel/3d/meshvp_per_pixel_light.h +++ b/code/nel/include/nel/3d/meshvp_per_pixel_light.h @@ -27,6 +27,7 @@ namespace NL3D { +class CVertexProgramPerPixelLight; /** * This vertex program is used to perform perpixel lighting with meshs. Its outputs are : @@ -49,6 +50,8 @@ namespace NL3D { class CMeshVPPerPixelLight : public IMeshVertexProgram { public: + friend class CVertexProgramPerPixelLight; + /// true if want Specular Lighting. bool SpecularLighting; public: @@ -84,7 +87,9 @@ private: bool _IsPointLight; // enum { NumVp = 8}; - static std::auto_ptr _VertexProgram[NumVp]; + static NLMISC::CSmartPtr _VertexProgram[NumVp]; + + NLMISC::CRefPtr _ActiveVertexProgram; }; } // NL3D diff --git a/code/nel/include/nel/3d/meshvp_wind_tree.h b/code/nel/include/nel/3d/meshvp_wind_tree.h index 7553d7cca..e2c790d6d 100644 --- a/code/nel/include/nel/3d/meshvp_wind_tree.h +++ b/code/nel/include/nel/3d/meshvp_wind_tree.h @@ -24,6 +24,7 @@ namespace NL3D { +class CVertexProgramWindTree; // *************************************************************************** /** @@ -35,6 +36,7 @@ namespace NL3D { class CMeshVPWindTree : public IMeshVertexProgram { public: + friend class CVertexProgramWindTree; enum {HrcDepth= 3}; @@ -104,6 +106,7 @@ public: // @} private: + static void initVertexPrograms(); void setupLighting(CScene *scene, CMeshBaseInstance *mbi, const NLMISC::CMatrix &invertedModelMat); private: @@ -112,7 +115,9 @@ private: /** The 16 versions: Specular or not (0 or 2), + normalize normal or not (0 or 1). * All multiplied by 4, because support from 0 to 3 pointLights activated. (0.., 4.., 8.., 12..) */ - static std::auto_ptr _VertexProgram[NumVp]; + static NLMISC::CSmartPtr _VertexProgram[NumVp]; + + NLMISC::CRefPtr _ActiveVertexProgram; // WindTree Time for this mesh param setup. Stored in mesh because same for all instances. float _CurrentTime[HrcDepth]; diff --git a/code/nel/include/nel/3d/pixel_program.h b/code/nel/include/nel/3d/pixel_program.h new file mode 100644 index 000000000..0787ae9fb --- /dev/null +++ b/code/nel/include/nel/3d/pixel_program.h @@ -0,0 +1,49 @@ +/** \file pixel_program.h + * Pixel program definition + */ + +/* Copyright, 2000, 2001 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. + */ + +#ifndef NL_PIXEL_PROGRAM_H +#define NL_PIXEL_PROGRAM_H + +#include +#include +#include + +#include + +namespace NL3D { + +class CPixelProgram : public IProgram +{ +public: + /// Constructor + CPixelProgram(); + /// Destructor + virtual ~CPixelProgram (); +}; + +} // NL3D + + +#endif // NL_PIXEL_PROGRAM_H + +/* End of vertex_program.h */ diff --git a/code/nel/include/nel/3d/program.h b/code/nel/include/nel/3d/program.h new file mode 100644 index 000000000..bbc4ab7db --- /dev/null +++ b/code/nel/include/nel/3d/program.h @@ -0,0 +1,358 @@ +/** + * \file program.h + * \brief IProgram + * \date 2013-09-07 15:00GMT + * \author Jan Boon (Kaetemi) + * IProgram + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifndef NL3D_PROGRAM_H +#define NL3D_PROGRAM_H +#include + +// STL includes + +// NeL includes +#include + +// Project includes + +namespace NL3D { + +// List typedef. +class IDriver; +class IProgramDrvInfos; +typedef std::list TGPUPrgDrvInfoPtrList; +typedef TGPUPrgDrvInfoPtrList::iterator ItGPUPrgDrvInfoPtrList; + +// Class for interaction of vertex program with Driver. +// IProgramDrvInfos represent the real data of the GPU program, stored into the driver (eg: just a GLint for opengl). +class IProgramDrvInfos : public NLMISC::CRefCount +{ +private: + IDriver *_Driver; + ItGPUPrgDrvInfoPtrList _DriverIterator; + +public: + IProgramDrvInfos (IDriver *drv, ItGPUPrgDrvInfoPtrList it); + // The virtual dtor is important. + virtual ~IProgramDrvInfos(void); + + virtual uint getUniformIndex(const char *name) const = 0; +}; + +// Features exposed by a program. Used to set builtin parameters on user provided shaders. +// This is only used for user provided shaders, not for builtin shaders, +// as it is a slow method which has to go through all of the options every time. +// Builtin shaders should set all flags to 0. +// Example: +// User shader flags Matrices in the Vertex Program: +// -> When rendering with a material, the driver will call setUniformDriver, +// which will check if the flag Matrices exists, and if so, it will use +// the index cache to find which matrices are needed by the shader, +// and set those which are found. +// This does not work extremely efficient, but it's the most practical option +// for passing builtin parameters onto user provided shaders. +// Note: May need additional flags related to scene sorting, etcetera. +struct CProgramFeatures +{ + CProgramFeatures() : DriverFlags(0), MaterialFlags(0) { } + + // Driver builtin parameters + enum TDriverFlags + { + // Matrices + Matrices = 0x00000001, + + // Fog + Fog = 0x00000002, + }; + uint32 DriverFlags; + + enum TMaterialFlags + { + /// Use the CMaterial texture stages as the textures for a Pixel Program + TextureStages = 0x00000001, + TextureMatrices = 0x00000002, + }; + // Material builtin parameters + uint32 MaterialFlags; +}; + +// Stucture used to cache the indices of builtin parameters which are used by the drivers +// Not used for parameters of specific nl3d programs +struct CProgramIndex +{ + enum TName + { + ModelView, + ModelViewInverse, + ModelViewTranspose, + ModelViewInverseTranspose, + + Projection, + ProjectionInverse, + ProjectionTranspose, + ProjectionInverseTranspose, + + ModelViewProjection, + ModelViewProjectionInverse, + ModelViewProjectionTranspose, + ModelViewProjectionInverseTranspose, + + Fog, + + FogStart, + FogEnd, + FogColor, + + Color, + DiffuseColor, + + Constant0, + Constant1, + Constant2, + Constant3, + + Sampler0, + Sampler1, + Sampler2, + Sampler3, + + TexMatrix0, + TexMatrix1, + TexMatrix2, + TexMatrix3, + + Light0DirOrPos, + Light1DirOrPos, + Light2DirOrPos, + Light3DirOrPos, + Light4DirOrPos, + Light5DirOrPos, + Light6DirOrPos, + Light7DirOrPos, + + Light0ColAmb, + Light1ColAmb, + Light2ColAmb, + Light3ColAmb, + Light4ColAmb, + Light5ColAmb, + Light6ColAmb, + Light7ColAmb, + + Light0ColDiff, + Light1ColDiff, + Light2ColDiff, + Light3ColDiff, + Light4ColDiff, + Light5ColDiff, + Light6ColDiff, + Light7ColDiff, + + Light0ColSpec, + Light1ColSpec, + Light2ColSpec, + Light3ColSpec, + Light4ColSpec, + Light5ColSpec, + Light6ColSpec, + Light7ColSpec, + + Light0Shininess, + Light1Shininess, + Light2Shininess, + Light3Shininess, + Light4Shininess, + Light5Shininess, + Light6Shininess, + Light7Shininess, + + Light0ConstAttn, + Light1ConstAttn, + Light2ConstAttn, + Light3ConstAttn, + Light4ConstAttn, + Light5ConstAttn, + Light6ConstAttn, + Light7ConstAttn, + + Light0LinAttn, + Light1LinAttn, + Light2LinAttn, + Light3LinAttn, + Light4LinAttn, + Light5LinAttn, + Light6LinAttn, + Light7LinAttn, + + Light0QuadAttn, + Light1QuadAttn, + Light2QuadAttn, + Light3QuadAttn, + Light4QuadAttn, + Light5QuadAttn, + Light6QuadAttn, + Light7QuadAttn, + + NUM_UNIFORMS + }; + static const char *Names[NUM_UNIFORMS]; + uint Indices[NUM_UNIFORMS]; +}; + +/** + * \brief IProgram + * \date 2013-09-07 15:00GMT + * \author Jan Boon (Kaetemi) + * A generic GPU program + */ +class IProgram : public NLMISC::CRefCount +{ +public: + enum TProfile + { + none = 0, + + // types + // Vertex Shader = 0x01 + // Pixel Shader = 0x02 + // Geometry Shader = 0x03 + + // nel - 0x31,type,bitfield + nelvp = 0x31010001, // VP supported by CVertexProgramParser, similar to arbvp1, can be translated to vs_1_1 + + // direct3d - 0xD9,type,major,minor + // vertex programs + vs_1_1 = 0xD9010101, + vs_2_0 = 0xD9010200, + // vs_2_sw = 0xD9010201, // not sure... + // vs_2_x = 0xD9010202, // not sure... + // vs_3_0 = 0xD9010300, // not supported + // pixel programs + ps_1_1 = 0xD9020101, + ps_1_2 = 0xD9020102, + ps_1_3 = 0xD9020103, + ps_1_4 = 0xD9020104, + ps_2_0 = 0xD9020200, + // ps_2_x = 0xD9020201, // not sure... + // ps_3_0 = 0xD9020300, // not supported + + // opengl - 0x61,type,bitfield + // vertex programs + // vp20 = 0x61010001, // NV_vertex_program1_1, outdated + arbvp1 = 0x61010002, // ARB_vertex_program + vp30 = 0x61010004, // NV_vertex_program2 + vp40 = 0x61010008, // NV_vertex_program3 + NV_fragment_program3 + gp4vp = 0x61010010, // NV_gpu_program4 + gp5vp = 0x61010020, // NV_gpu_program5 + // pixel programs + // fp20 = 0x61020001, // very limited and outdated, unnecessary + // fp30 = 0x61020002, // NV_fragment_program, now arbfp1, redundant + arbfp1 = 0x61020004, // ARB_fragment_program + fp40 = 0x61020008, // NV_fragment_program2, arbfp1 with "OPTION NV_fragment_program2;\n" + gp4fp = 0x61020010, // NV_gpu_program4 + gp5fp = 0x61020020, // NV_gpu_program5 + // geometry programs + gp4gp = 0x61030001, // NV_gpu_program4 + gp5gp = 0x61030001, // NV_gpu_program5 + + // glsl - 0x65,type,version + glsl330v = 0x65010330, // GLSL vertex program version 330 + glsl330f = 0x65020330, // GLSL fragment program version 330 + glsl330g = 0x65030330, // GLSL geometry program version 330 + }; + + struct CSource : public NLMISC::CRefCount + { + public: + std::string DisplayName; + + /// Minimal required profile for this GPU program + IProgram::TProfile Profile; + + const char *SourcePtr; + size_t SourceLen; + /// Copy the source code string + inline void setSource(const std::string &source) { SourceCopy = source; SourcePtr = &SourceCopy[0]; SourceLen = SourceCopy.size(); } + inline void setSource(const char *source) { SourceCopy = source; SourcePtr = &SourceCopy[0]; SourceLen = SourceCopy.size(); } + /// Set pointer to source code string without copying the string + inline void setSourcePtr(const char *sourcePtr, size_t sourceLen) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = sourceLen; } + inline void setSourcePtr(const char *sourcePtr) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = strlen(sourcePtr); } + + /// CVertexProgramInfo/CPixelProgramInfo/... NeL features + CProgramFeatures Features; + + /// Map with known parameter indices, used for assembly programs + std::map ParamIndices; + + private: + std::string SourceCopy; + }; + +public: + IProgram(); + virtual ~IProgram(); + + // Manage the sources, not allowed after compilation. + // Add multiple sources using different profiles, the driver will use the first one it supports. + inline size_t getSourceNb() const { return m_Sources.size(); }; + inline CSource *getSource(size_t i) const { return m_Sources[i]; }; + inline size_t addSource(CSource *source) { nlassert(!m_Source); m_Sources.push_back(source); return (m_Sources.size() - 1); } + inline void removeSource(size_t i) { nlassert(!m_Source); m_Sources.erase(m_Sources.begin() + i); } + + // Get the idx of a parameter (ogl: uniform, d3d: constant, etcetera) by name. Invalid name returns ~0 + inline uint getUniformIndex(const char *name) const { return m_DrvInfo->getUniformIndex(name); }; + inline uint getUniformIndex(const std::string &name) const { return m_DrvInfo->getUniformIndex(name.c_str()); }; + inline uint getUniformIndex(CProgramIndex::TName name) const { return m_Index.Indices[name]; } + + // Get feature information of the current program + inline CSource *source() const { return m_Source; }; + inline const CProgramFeatures &features() const { return m_Source->Features; }; + inline TProfile profile() const { return m_Source->Profile; } + + // Build feature info, called automatically by the driver after compile succeeds + void buildInfo(CSource *source); + + // Override this to build additional info in a subclass + virtual void buildInfo(); + +protected: + /// The progam source + std::vector > m_Sources; + + /// The source used for compilation + NLMISC::CSmartPtr m_Source; + CProgramIndex m_Index; + +public: + /// The driver information. For the driver implementation only. + NLMISC::CRefPtr m_DrvInfo; + +}; /* class IProgram */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_PROGRAM_H */ + +/* end of file */ diff --git a/code/nel/include/nel/3d/render_trav.h b/code/nel/include/nel/3d/render_trav.h index 6e8d04b32..d50d2c242 100644 --- a/code/nel/include/nel/3d/render_trav.h +++ b/code/nel/include/nel/3d/render_trav.h @@ -27,6 +27,7 @@ #include "nel/3d/mesh_block_manager.h" #include "nel/3d/shadow_map_manager.h" #include "nel/3d/u_scene.h" +#include "nel/3d/vertex_program.h" #include @@ -68,6 +69,41 @@ class CWaterModel; #define NL3D_SHADOW_MESH_SKIN_MANAGER_MAXVERTICES 3000 #define NL3D_SHADOW_MESH_SKIN_MANAGER_NUMVB 8 +/// Container for lighted vertex program. +class CVertexProgramLighted : public CVertexProgram +{ +public: + static const uint MaxLight = 4; + static const uint MaxPointLight = (MaxLight - 1); + struct CIdxLighted + { + uint Ambient; + uint Diffuse[MaxLight]; + uint Specular[MaxLight]; + uint DirOrPos[MaxLight]; // light 0, directional sun; light 1,2,3, omni point light + uint EyePosition; + uint DiffuseAlpha; + }; + struct CFeaturesLighted + { + /// Number of point lights that this program is generated for, varies from 0 to 3. + uint NumActivePointLights; + bool SupportSpecular; + bool Normalize; + /// Start of constants to use for lighting with assembly shaders. + uint CtStartNeLVP; + }; + CVertexProgramLighted() { } + virtual ~CVertexProgramLighted() { } + virtual void buildInfo(); + const CIdxLighted &idxLighted() const { return m_IdxLighted; } + const CFeaturesLighted &featuresLighted() const { return m_FeaturesLighted; } + +protected: + CIdxLighted m_IdxLighted; + CFeaturesLighted m_FeaturesLighted; + +}; // *************************************************************************** @@ -224,7 +260,7 @@ public: // @{ // Max VP Light setup Infos. - enum {MaxVPLight= 4}; + enum {MaxVPLight = CVertexProgramLighted::MaxLight}; /** reset the lighting setup in the driver (all lights are disabled). * called at beginning of traverse(). Must be called by any model (before and after rendering) @@ -244,7 +280,8 @@ public: */ void changeLightSetup(CLightContribution *lightContribution, bool useLocalAttenuation); - + /// Must call before beginVPLightSetup + void prepareVPLightSetup(); /** setup the driver VP constants to get info from current LightSetup. * Only 0..3 Light + SunLights are supported. The VP do NOT support distance/Spot attenuation * Also it does not handle World Matrix with non uniform scale correctly since lighting is made in ObjectSpace @@ -253,7 +290,7 @@ public: * \param supportSpecular asitsounds. PointLights and dirLight are localViewer * \param invObjectWM the inverse of object matrix: lights are mul by this. Vp compute in object space. */ - void beginVPLightSetup(uint ctStart, bool supportSpecular, const CMatrix &invObjectWM); + void beginVPLightSetup(CVertexProgramLighted *program, const CMatrix &invObjectWM); /** change the driver VP LightSetup constants which depends on material. * \param excludeStrongest This remove the strongest light from the setup. The typical use is to have it computed by using perpixel lighting. @@ -299,7 +336,8 @@ public: * \param numActivePoinLights tells how many point light from 0 to 3 this VP must handle. NB: the Sun directionnal is not option * NB: nlassert(numActiveLights<=MaxVPLight-1). */ - static std::string getLightVPFragment(uint numActivePointLights, uint ctStart, bool supportSpecular, bool normalize); + static std::string getLightVPFragmentNeLVP(uint numActivePointLights, uint ctStart, bool supportSpecular, bool normalize); + // TODO_VP_GLSL /** This returns a reference to a driver light, by its index * \see getStrongestLightIndex @@ -381,12 +419,14 @@ private: mutable uint _StrongestLightIndex; mutable bool _StrongestLightTouched; + // Current vp setuped with beginVPLightSetup() + NLMISC::CRefPtr _VPCurrent; // Current ctStart setuped with beginVPLightSetup() - uint _VPCurrentCtStart; + //uint _VPCurrentCtStart; // Current num of VP lights enabled. uint _VPNumLights; // Current support of specular - bool _VPSupportSpecular; + // bool _VPSupportSpecular; // Sum of all ambiant of all lights + ambiantGlobal. NLMISC::CRGBAF _VPFinalAmbient; // Diffuse/Spec comp of all light / 255. diff --git a/code/nel/include/nel/3d/scene.h b/code/nel/include/nel/3d/scene.h index 1d54ce7a6..e0648ebd3 100644 --- a/code/nel/include/nel/3d/scene.h +++ b/code/nel/include/nel/3d/scene.h @@ -826,7 +826,8 @@ private: void flushSSSModelRequests(); // common vb for water display CVertexBuffer _WaterVB; - + + bool _RequestParticlesAnimate; }; diff --git a/code/nel/include/nel/3d/shader.h b/code/nel/include/nel/3d/shader.h deleted file mode 100644 index 3377c27d4..000000000 --- a/code/nel/include/nel/3d/shader.h +++ /dev/null @@ -1,99 +0,0 @@ -// NeL - MMORPG Framework -// 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 . - -#ifndef NL_SHADER_H -#define NL_SHADER_H - -#include "nel/misc/types_nl.h" -#include "nel/misc/smart_ptr.h" -#include - - -namespace NL3D { - -using NLMISC::CRefCount; - - -class IDriver; - -// List typedef. -class IShaderDrvInfos; -typedef std::list TShaderDrvInfoPtrList; -typedef TShaderDrvInfoPtrList::iterator ItShaderDrvInfoPtrList; - -/** - * Interface for shader driver infos. - */ -class IShaderDrvInfos : public CRefCount -{ -private: - IDriver *_Driver; - ItShaderDrvInfoPtrList _DriverIterator; - -public: - IShaderDrvInfos(IDriver *drv, ItShaderDrvInfoPtrList it) {_Driver= drv; _DriverIterator= it;} - // The virtual dtor is important. - virtual ~IShaderDrvInfos(); -}; - - -/** - * Shader resource for the driver. It is just a container for a ".fx" text file. - */ -/* *** IMPORTANT ******************** - * *** IF YOU MODIFY THE STRUCTURE OF THIS CLASS, PLEASE INCREMENT IDriver::InterfaceVersion TO INVALIDATE OLD DRIVER DLL - * ********************************** - */ -// -------------------------------------------------- -class CShader -{ -public: - CShader(); - ~CShader(); - - // Load a shader file - bool loadShaderFile (const char *filename); - - // Set the shader text - void setText (const char *text); - - // Get the shader text - const char *getText () const { return _Text.c_str(); } - - // Set the shader name - void setName (const char *name); - - // Get the shader name - const char *getName () const { return _Name.c_str(); } - -public: - // Private. For Driver only. - bool _ShaderChanged; - NLMISC::CRefPtr _DrvInfo; -private: - // The shader - std::string _Text; - // The shader name - std::string _Name; -}; - - -} // NL3D - - -#endif // NL_SHADER_H - -/* End of shader.h */ diff --git a/code/nel/include/nel/3d/stereo_debugger.h b/code/nel/include/nel/3d/stereo_debugger.h new file mode 100644 index 000000000..b07a9630c --- /dev/null +++ b/code/nel/include/nel/3d/stereo_debugger.h @@ -0,0 +1,134 @@ +/** + * \file stereo_debugger.h + * \brief CStereoDebugger + * \date 2013-07-03 20:17GMT + * \author Jan Boon (Kaetemi) + * CStereoDebugger + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#if !FINAL_VERSION +#ifndef NL3D_STEREO_DEBUGGER_H +#define NL3D_STEREO_DEBUGGER_H +#include + +// STL includes + +// NeL includes +#include +#include + +// Project includes +#include +#include +#include +#include + +#define NL_STEREO_MAX_USER_CAMERAS 8 + +namespace NL3D { + +class ITexture; +class CTextureUser; +class CPixelProgram; + +/** + * \brief CStereoDebugger + * \date 2013-07-03 20:17GMT + * \author Jan Boon (Kaetemi) + * CStereoDebugger + */ +class CStereoDebugger : public IStereoDisplay +{ +public: + CStereoDebugger(); + virtual ~CStereoDebugger(); + + + /// Sets driver and generates necessary render targets + virtual void setDriver(NL3D::UDriver *driver); + void releaseTextures(); + void initTextures(); + void setTextures(); + void verifyTextures(); + + /// Gets the required screen resolution for this device + virtual bool getScreenResolution(uint &width, uint &height); + /// Set latest camera position etcetera + virtual void updateCamera(uint cid, const NL3D::UCamera *camera); + /// Get the frustum to use for clipping + virtual void getClippingFrustum(uint cid, NL3D::UCamera *camera) const; + + /// Is there a next pass + virtual bool nextPass(); + /// Gets the current viewport + virtual const NL3D::CViewport &getCurrentViewport() const; + /// Gets the current camera frustum + virtual const NL3D::CFrustum &getCurrentFrustum(uint cid) const; + /// Gets the current camera frustum + virtual void getCurrentFrustum(uint cid, NL3D::UCamera *camera) const; + /// Gets the current camera matrix + virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const; + + /// At the start of a new render target + virtual bool wantClear(); + /// The 3D scene + virtual bool wantScene(); + /// Interface within the 3D scene + virtual bool wantInterface3D(); + /// 2D Interface + virtual bool wantInterface2D(); + + /// Returns true if a new render target was set, always fase if not using render targets + virtual bool beginRenderTarget(); + /// Returns true if a render target was fully drawn, always false if not using render targets + virtual bool endRenderTarget(); + + + static void listDevices(std::vector &devicesOut); + +private: + UDriver *m_Driver; + + int m_Stage; + int m_SubStage; + + CViewport m_LeftViewport; + CViewport m_RightViewport; + CFrustum m_Frustum[NL_STEREO_MAX_USER_CAMERAS]; + CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; + + NLMISC::CSmartPtr m_LeftTex; + NL3D::CTextureUser *m_LeftTexU; + NLMISC::CSmartPtr m_RightTex; + NL3D::CTextureUser *m_RightTexU; + NL3D::UMaterial m_Mat; + NLMISC::CQuadUV m_QuadUV; + CPixelProgram *m_PixelProgram; + +}; /* class CStereoDebugger */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_STEREO_DEBUGGER_H */ +#endif /* #if !FINAL_VERSION */ + +/* end of file */ diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h new file mode 100644 index 000000000..e3b5b3716 --- /dev/null +++ b/code/nel/include/nel/3d/stereo_display.h @@ -0,0 +1,141 @@ +/** + * \file stereo_display.h + * \brief IStereoDisplay + * \date 2013-06-27 16:29GMT + * \author Jan Boon (Kaetemi) + * IStereoDisplay + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifndef NL3D_STEREO_DISPLAY_H +#define NL3D_STEREO_DISPLAY_H +#include + +// STL includes + +// NeL includes +#include + +// Project includes + +namespace NL3D { + +class UCamera; +class CViewport; +class CFrustum; +class IStereoDisplay; +class UTexture; +class UDriver; + +class IStereoDeviceFactory : public NLMISC::CRefCount +{ +public: + IStereoDeviceFactory() { } + virtual ~IStereoDeviceFactory() { } + virtual IStereoDisplay *createDevice() const = 0; +}; + +struct CStereoDeviceInfo +{ +public: + enum TStereoDeviceClass + { + StereoDisplay, + StereoHMD, + }; + + enum TStereoDeviceLibrary + { + NeL3D, + OVR, + LibVR, + OpenHMD, + }; + + NLMISC::CSmartPtr Factory; + + TStereoDeviceLibrary Library; + TStereoDeviceClass Class; + std::string Manufacturer; + std::string ProductName; + std::string Serial; // A unique device identifier +}; + +/** + * \brief IStereoDisplay + * \date 2013-06-27 16:29GMT + * \author Jan Boon (Kaetemi) + * IStereoDisplay + */ +class IStereoDisplay +{ +public: + IStereoDisplay(); + virtual ~IStereoDisplay(); + + /// Sets driver and generates necessary render targets + virtual void setDriver(NL3D::UDriver *driver) = 0; + + /// Gets the required screen resolution for this device + virtual bool getScreenResolution(uint &width, uint &height) = 0; + /// Set latest camera position etcetera + virtual void updateCamera(uint cid, const NL3D::UCamera *camera) = 0; + /// Get the frustum to use for clipping + virtual void getClippingFrustum(uint cid, NL3D::UCamera *camera) const = 0; + + /// Is there a next pass + virtual bool nextPass() = 0; + /// Gets the current viewport + virtual const NL3D::CViewport &getCurrentViewport() const = 0; + /// Gets the current camera frustum + virtual const NL3D::CFrustum &getCurrentFrustum(uint cid) const = 0; + /// Gets the current camera frustum + virtual void getCurrentFrustum(uint cid, NL3D::UCamera *camera) const = 0; + /// Gets the current camera matrix + virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const = 0; + + /// At the start of a new render target + virtual bool wantClear() = 0; + /// The 3D scene + virtual bool wantScene() = 0; + /// Interface within the 3D scene + virtual bool wantInterface3D() = 0; + /// 2D Interface + virtual bool wantInterface2D() = 0; + + /// Returns true if a new render target was set, always fase if not using render targets + virtual bool beginRenderTarget() = 0; + /// Returns true if a render target was fully drawn, always false if not using render targets + virtual bool endRenderTarget() = 0; + + static const char *getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library); + static void listDevices(std::vector &devicesOut); + static IStereoDisplay *createDevice(const CStereoDeviceInfo &deviceInfo); + static void releaseUnusedLibraries(); + static void releaseAllLibraries(); + +}; /* class IStereoDisplay */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_STEREO_DISPLAY_H */ + +/* end of file */ diff --git a/code/nel/include/nel/3d/stereo_hmd.h b/code/nel/include/nel/3d/stereo_hmd.h new file mode 100644 index 000000000..95c159cfd --- /dev/null +++ b/code/nel/include/nel/3d/stereo_hmd.h @@ -0,0 +1,73 @@ +/** + * \file stereo_hmd.h + * \brief IStereoHMD + * \date 2013-06-27 16:30GMT + * \author Jan Boon (Kaetemi) + * IStereoHMD + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifndef NL3D_STEREO_HMD_H +#define NL3D_STEREO_HMD_H +#include + +// STL includes + +// NeL includes + +// Project includes +#include + +namespace NL3D { + +/** + * \brief IStereoHMD + * \date 2013-06-27 16:30GMT + * \author Jan Boon (Kaetemi) + * IStereoHMD + */ +class IStereoHMD : public IStereoDisplay +{ +public: + IStereoHMD(); + virtual ~IStereoHMD(); + + /// Get the HMD orientation + virtual NLMISC::CQuat getOrientation() const = 0; + + /// Get GUI center (1 = width, 1 = height, 0 = center) + virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const = 0; + + /// Set the head model, eye position relative to orientation point + virtual void setEyePosition(const NLMISC::CVector &v) = 0; + /// Get the head model, eye position relative to orientation point + virtual const NLMISC::CVector &getEyePosition() const = 0; + + /// Set the scale of the game in units per meter + virtual void setScale(float s) = 0; + +}; /* class IStereoHMD */ + +} /* namespace NL3D */ + +#endif /* #ifndef NL3D_STEREO_HMD_H */ + +/* end of file */ diff --git a/code/nel/include/nel/3d/stereo_libvr.h b/code/nel/include/nel/3d/stereo_libvr.h new file mode 100644 index 000000000..76d1966fe --- /dev/null +++ b/code/nel/include/nel/3d/stereo_libvr.h @@ -0,0 +1,160 @@ +/** + * \file stereo_libvr.h + * \brief CStereoLibVR + * \date 2013-08-19 19:17MT + * \author Thibaut Girka (ThibG) + * CStereoLibVR + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifndef NL3D_STEREO_LIBVR_H +#define NL3D_STEREO_LIBVR_H + +#ifdef HAVE_LIBVR + +#include + +// STL includes + +// NeL includes +#include +#include + +// Project includes +#include +#include +#include +#include + +namespace NL3D { + +class ITexture; +class CTextureUser; +class CStereoLibVRDevicePtr; +class CStereoLibVRDeviceHandle; +class CPixelProgram; + +#define NL_STEREO_MAX_USER_CAMERAS 8 + +/** + * \brief CStereoOVR + * \date 2013-06-25 22:22GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ +class CStereoLibVR : public IStereoHMD +{ +public: + CStereoLibVR(const CStereoLibVRDeviceHandle *handle); + virtual ~CStereoLibVR(); + + /// Sets driver and generates necessary render targets + virtual void setDriver(NL3D::UDriver *driver); + + /// Gets the required screen resolution for this device + virtual bool getScreenResolution(uint &width, uint &height); + /// Set latest camera position etcetera + virtual void updateCamera(uint cid, const NL3D::UCamera *camera); + /// Get the frustum to use for clipping + virtual void getClippingFrustum(uint cid, NL3D::UCamera *camera) const; + + /// Is there a next pass + virtual bool nextPass(); + /// Gets the current viewport + virtual const NL3D::CViewport &getCurrentViewport() const; + /// Gets the current camera frustum + virtual const NL3D::CFrustum &getCurrentFrustum(uint cid) const; + /// Gets the current camera frustum + virtual void getCurrentFrustum(uint cid, NL3D::UCamera *camera) const; + /// Gets the current camera matrix + virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const; + + /// At the start of a new render target + virtual bool wantClear(); + /// The 3D scene + virtual bool wantScene(); + /// Interface within the 3D scene + virtual bool wantInterface3D(); + /// 2D Interface + virtual bool wantInterface2D(); + + /// Returns true if a new render target was set, always fase if not using render targets + virtual bool beginRenderTarget(); + /// Returns true if a render target was fully drawn, always false if not using render targets + virtual bool endRenderTarget(); + + + /// Get the HMD orientation + virtual NLMISC::CQuat getOrientation() const; + + /// Get GUI center (1 = width, 1 = height, 0 = center) + virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const; + + /// Set the head model, eye position relative to orientation point + virtual void setEyePosition(const NLMISC::CVector &v); + /// Get the head model, eye position relative to orientation point + virtual const NLMISC::CVector &getEyePosition() const; + + /// Set the scale of the game in units per meter + virtual void setScale(float s); + + + static void listDevices(std::vector &devicesOut); + static bool isLibraryInUse(); + static void releaseLibrary(); + + + /// Calculates internal camera information based on the reference camera + void initCamera(uint cid, const NL3D::UCamera *camera); + /// Checks if the device used by this class was actually created + bool isDeviceCreated(); + +private: + CStereoLibVRDevicePtr *m_DevicePtr; + int m_Stage; + int m_SubStage; + CViewport m_LeftViewport; + CViewport m_RightViewport; + CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; + mutable bool m_OrientationCached; + mutable NLMISC::CQuat m_OrientationCache; + UDriver *m_Driver; + NLMISC::CSmartPtr m_BarrelTex; + NL3D::CTextureUser *m_BarrelTexU; + NL3D::UMaterial m_BarrelMat; + NLMISC::CQuadUV m_BarrelQuadLeft; + NLMISC::CQuadUV m_BarrelQuadRight; + CPixelProgram *m_PixelProgram; + NLMISC::CVector m_EyePosition; + float m_Scale; + +}; /* class CStereoLibVR */ + +} /* namespace NL3D */ + +#endif /* HAVE_LIBVR */ + +#endif /* #ifndef NL3D_STEREO_LIBVR_H */ + +/* end of file */ diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h new file mode 100644 index 000000000..ba6895bf0 --- /dev/null +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -0,0 +1,176 @@ +/** + * \file stereo_ovr.h + * \brief CStereoOVR + * \date 2013-06-25 22:22GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + * + * Linking this library statically or dynamically with other modules + * is making a combined work based on this library. Thus, the terms + * and conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give + * you permission to link this library with the Oculus SDK to produce + * an executable, regardless of the license terms of the Oculus SDK, + * and distribute linked combinations including the two, provided that + * you also meet the terms and conditions of the license of the Oculus + * SDK. You must obey the GNU General Public License in all respects + * for all of the code used other than the Oculus SDK. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. + */ + +#ifndef NL3D_STEREO_OVR_H +#define NL3D_STEREO_OVR_H + +#ifdef HAVE_LIBOVR + +#include + +// STL includes + +// NeL includes +#include +#include + +// Project includes +#include +#include +#include +#include + +namespace NL3D { + +class ITexture; +class CTextureUser; +class CStereoOVRDevicePtr; +class CStereoOVRDeviceHandle; +class CPixelProgramOVR; + +#define NL_STEREO_MAX_USER_CAMERAS 8 + +/** + * \brief CStereoOVR + * \date 2013-06-25 22:22GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ +class CStereoOVR : public IStereoHMD +{ +public: + CStereoOVR(const CStereoOVRDeviceHandle *handle); + virtual ~CStereoOVR(); + + /// Sets driver and generates necessary render targets + virtual void setDriver(NL3D::UDriver *driver); + + /// Gets the required screen resolution for this device + virtual bool getScreenResolution(uint &width, uint &height); + /// Set latest camera position etcetera + virtual void updateCamera(uint cid, const NL3D::UCamera *camera); + /// Get the frustum to use for clipping + virtual void getClippingFrustum(uint cid, NL3D::UCamera *camera) const; + + /// Is there a next pass + virtual bool nextPass(); + /// Gets the current viewport + virtual const NL3D::CViewport &getCurrentViewport() const; + /// Gets the current camera frustum + virtual const NL3D::CFrustum &getCurrentFrustum(uint cid) const; + /// Gets the current camera frustum + virtual void getCurrentFrustum(uint cid, NL3D::UCamera *camera) const; + /// Gets the current camera matrix + virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const; + + /// At the start of a new render target + virtual bool wantClear(); + /// The 3D scene + virtual bool wantScene(); + /// Interface within the 3D scene + virtual bool wantInterface3D(); + /// 2D Interface + virtual bool wantInterface2D(); + + /// Returns true if a new render target was set, always fase if not using render targets + virtual bool beginRenderTarget(); + /// Returns true if a render target was fully drawn, always false if not using render targets + virtual bool endRenderTarget(); + + + /// Get the HMD orientation + virtual NLMISC::CQuat getOrientation() const; + + /// Get GUI center (1 = width, 1 = height, 0 = center) + virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const; + + /// Set the head model, eye position relative to orientation point + virtual void setEyePosition(const NLMISC::CVector &v); + /// Get the head model, eye position relative to orientation point + virtual const NLMISC::CVector &getEyePosition() const; + + /// Set the scale of the game in units per meter + virtual void setScale(float s); + + + static void listDevices(std::vector &devicesOut); + static bool isLibraryInUse(); + static void releaseLibrary(); + + + /// Calculates internal camera information based on the reference camera + void initCamera(uint cid, const NL3D::UCamera *camera); + /// Checks if the device used by this class was actually created + bool isDeviceCreated(); + +private: + CStereoOVRDevicePtr *m_DevicePtr; + int m_Stage; + int m_SubStage; + CViewport m_LeftViewport; + CViewport m_RightViewport; + CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; + mutable bool m_OrientationCached; + mutable NLMISC::CQuat m_OrientationCache; + UDriver *m_Driver; + NLMISC::CSmartPtr m_BarrelTex; + NL3D::CTextureUser *m_BarrelTexU; + NL3D::UMaterial m_BarrelMat; + NLMISC::CQuadUV m_BarrelQuadLeft; + NLMISC::CQuadUV m_BarrelQuadRight; + NLMISC::CRefPtr m_PixelProgram; + NLMISC::CVector m_EyePosition; + float m_Scale; + +}; /* class CStereoOVR */ + +} /* namespace NL3D */ + +#endif /* HAVE_LIBOVR */ + +#endif /* #ifndef NL3D_STEREO_OVR_H */ + +/* end of file */ diff --git a/code/nel/include/nel/3d/u_driver.h b/code/nel/include/nel/3d/u_driver.h index d11602bbb..7e0138292 100644 --- a/code/nel/include/nel/3d/u_driver.h +++ b/code/nel/include/nel/3d/u_driver.h @@ -168,6 +168,7 @@ public: */ // @{ virtual void disableHardwareVertexProgram()=0; + virtual void disableHardwarePixelProgram()=0; virtual void disableHardwareVertexArrayAGP()=0; virtual void disableHardwareTextureShader()=0; // @} @@ -672,13 +673,6 @@ public: */ virtual void forceTextureResize(uint divisor)=0; - /** Sets enforcement of native fragment programs. This is by default enabled. - * - * \param nativeOnly If set to false, fragment programs don't need to be native to stay loaded, - * otherwise (aka if true) they will be purged. - */ - virtual void forceNativeFragmentPrograms(bool nativeOnly) = 0; - /** Setup monitor color properties. * * Return false if setup failed. diff --git a/code/nel/include/nel/3d/vegetable_manager.h b/code/nel/include/nel/3d/vegetable_manager.h index 71ed235e4..ee21af3f3 100644 --- a/code/nel/include/nel/3d/vegetable_manager.h +++ b/code/nel/include/nel/3d/vegetable_manager.h @@ -48,6 +48,7 @@ class CVegetableLightEx; // default distance is 60 meters. #define NL3D_VEGETABLE_DEFAULT_DIST_MAX 60.f +class CVertexProgramVeget; // *************************************************************************** /** @@ -306,7 +307,8 @@ private: // The same, but no VBHard. CVegetableVBAllocator _VBSoftAllocator[CVegetableVBAllocator::VBTypeCount]; // Vertex Program. One VertexProgram for each rdrPass (with / without fog) - CVertexProgram *_VertexProgram[NL3D_VEGETABLE_NRDRPASS][2]; + CSmartPtr _VertexProgram[NL3D_VEGETABLE_NRDRPASS][2]; + CRefPtr _ActiveVertexProgram; // Material. Useful for texture and alphaTest @@ -342,7 +344,7 @@ private: /// setup the vertexProgram constants. - void setupVertexProgramConstants(IDriver *driver); + void setupVertexProgramConstants(IDriver *driver, bool fogEnabled); /** swap the RdrPass type (hard or soft) of the rdrPass of an instance group. diff --git a/code/nel/include/nel/3d/vertex_program.h b/code/nel/include/nel/3d/vertex_program.h index 903e5ccf7..3d77c6104 100644 --- a/code/nel/include/nel/3d/vertex_program.h +++ b/code/nel/include/nel/3d/vertex_program.h @@ -19,90 +19,24 @@ #include "nel/misc/types_nl.h" #include "nel/misc/smart_ptr.h" +#include "nel/3d/program.h" #include - namespace NL3D { -// List typedef. -class IDriver; -class IVertexProgramDrvInfos; -typedef std::list TVtxPrgDrvInfoPtrList; -typedef TVtxPrgDrvInfoPtrList::iterator ItVtxPrgDrvInfoPtrList; - -// Class for interaction of vertex program with Driver. -// IVertexProgramDrvInfos represent the real data of the vertex program, stored into the driver (eg: just a GLint for opengl). -class IVertexProgramDrvInfos : public NLMISC::CRefCount +class CVertexProgram : public IProgram { -private: - IDriver *_Driver; - ItVtxPrgDrvInfoPtrList _DriverIterator; - public: - IVertexProgramDrvInfos (IDriver *drv, ItVtxPrgDrvInfoPtrList it); - // The virtual dtor is important. - virtual ~IVertexProgramDrvInfos(void); -}; - - -/** - * This class is a vertex program. - * - * D3D / OPENGL compatibility notes: - * --------------------------------- - * - * To make your program compatible with D3D and OPENGL nel drivers, please follow thoses directives to write your vertex programs - * - * - Use only v[0], v[1] etc.. syntax for input registers. Don't use v0, v1 or v[OPOS] etc.. - * - Use only c[0], c[1] etc.. syntax for constant registers. Don't use c0, c1 etc.. - * - Use only o[HPOS], o[COL0] etc.. syntax for output registers. Don't use oPos, oD0 etc.. - * - Use only uppercase for registers R1, R2 etc.. Don't use lowercase r1, r2 etc.. - * - Use a semicolon to delineate instructions. - * - Use ARL instruction to load the adress register and not MOV. - * - Don't use the NOP instruction. - * - Don't use macros. - * - * -> Thoses programs work without any change under OpenGL. - * -> Direct3D driver implementation will have to modify the syntax on the fly before the setup like this: - * - "v[0]" must be changed in "v0" etc.. - * - "o[HPOS]" must be changed in oPos etc.. - * - Semicolon must be changed in line return character. - * - ARL instruction must be changed in MOV. - * - * Behaviour of LOG may change depending on implementation: You can only expect to have dest.z = log2(abs(src.w)). - * LIT may or may not clamp the specular exponent to [-128, 128] (not done when EXT_vertex_shader is used for example ..) - * - * Depending on the implementation, some optimizations can be achieved by masking the unused output values of instructions - * as LIT, EXPP .. - * - * \author Cyril 'Hulud' Corvazier - * \author Nevrax France - * \date 2001 - */ -class CVertexProgram : public NLMISC::CRefCount -{ -public: - /// Constructor - CVertexProgram (const char* program); + CVertexProgram(); + CVertexProgram(const char *nelvp); /// Destructor virtual ~CVertexProgram (); - /// Get the program - const std::string& getProgram () const { return _Program; }; - -private: - /// The progam - std::string _Program; - -public: - /// The driver information. For the driver implementation only. - NLMISC::CRefPtr _DrvInfo; }; - } // NL3D diff --git a/code/nel/include/nel/3d/vertex_program_parse.h b/code/nel/include/nel/3d/vertex_program_parse.h index cd9f414c9..88538da07 100644 --- a/code/nel/include/nel/3d/vertex_program_parse.h +++ b/code/nel/include/nel/3d/vertex_program_parse.h @@ -21,6 +21,40 @@ #include +/** + * This class is a vertex program. + * + * D3D / OPENGL compatibility notes: + * --------------------------------- + * + * To make your program compatible with D3D and OPENGL nel drivers, please follow thoses directives to write your vertex programs + * + * - Use only v[0], v[1] etc.. syntax for input registers. Don't use v0, v1 or v[OPOS] etc.. + * - Use only c[0], c[1] etc.. syntax for constant registers. Don't use c0, c1 etc.. + * - Use only o[HPOS], o[COL0] etc.. syntax for output registers. Don't use oPos, oD0 etc.. + * - Use only uppercase for registers R1, R2 etc.. Don't use lowercase r1, r2 etc.. + * - Use a semicolon to delineate instructions. + * - Use ARL instruction to load the adress register and not MOV. + * - Don't use the NOP instruction. + * - Don't use macros. + * + * -> Thoses programs work without any change under OpenGL. + * -> Direct3D driver implementation will have to modify the syntax on the fly before the setup like this: + * - "v[0]" must be changed in "v0" etc.. + * - "o[HPOS]" must be changed in oPos etc.. + * - Semicolon must be changed in line return character. + * - ARL instruction must be changed in MOV. + * + * Behaviour of LOG may change depending on implementation: You can only expect to have dest.z = log2(abs(src.w)). + * LIT may or may not clamp the specular exponent to [-128, 128] (not done when EXT_vertex_shader is used for example ..) + * + * Depending on the implementation, some optimizations can be achieved by masking the unused output values of instructions + * as LIT, EXPP .. + * + * \author Cyril 'Hulud' Corvazier + * \author Nevrax France + * \date 2001 + */ /// Swizzle of an operand in a vertex program struct CVPSwizzle diff --git a/code/nel/include/nel/3d/water_env_map.h b/code/nel/include/nel/3d/water_env_map.h index 384f55b56..50fca18ec 100644 --- a/code/nel/include/nel/3d/water_env_map.h +++ b/code/nel/include/nel/3d/water_env_map.h @@ -61,7 +61,7 @@ public: // Get envmap 2D texture (after projection of cube map) ITexture *getEnvMap2D() const { return _Env2D; } // tmp for debug : render test mesh with current model / view matrixs - void renderTestMesh(IDriver &driver); + // void renderTestMesh(IDriver &driver); // set constant alpha of envmap void setAlpha(uint8 alpha) { _Alpha = alpha; } uint8 getAlpha() const { return _Alpha; } diff --git a/code/nel/include/nel/3d/water_shape.h b/code/nel/include/nel/3d/water_shape.h index f7a7e1b0b..dc7f20426 100644 --- a/code/nel/include/nel/3d/water_shape.h +++ b/code/nel/include/nel/3d/water_shape.h @@ -49,6 +49,29 @@ const NLMISC::CClassId WaveMakerModelClassId = NLMISC::CClassId(0x16da3356, 0x7 const uint WATER_VERTEX_HARD_SIZE = sizeof(float[3]); const uint WATER_VERTEX_SOFT_SIZE = sizeof(float[5]); +// VP Water No Wave +class CVertexProgramWaterVPNoWave : public CVertexProgram +{ +public: + struct CIdx + { + uint BumpMap0Scale; + uint BumpMap0Offset; + uint BumpMap1Scale; + uint BumpMap1Offset; + uint ObserverHeight; + uint ScaleReflectedRay; + uint DiffuseMapVector0; + uint DiffuseMapVector1; + }; + CVertexProgramWaterVPNoWave(bool diffuse); + virtual ~CVertexProgramWaterVPNoWave() { } + virtual void buildInfo(); + inline const CIdx &idx() const { return m_Idx; } +private: + CIdx m_Idx; + bool m_Diffuse; +}; /** * A water shape. @@ -247,17 +270,17 @@ private: static bool _GridSizeTouched; // - static std::auto_ptr _VertexProgramBump1; - static std::auto_ptr _VertexProgramBump2; + /*static NLMISC::CSmartPtr _VertexProgramBump1; + static NLMISC::CSmartPtr _VertexProgramBump2; // - static std::auto_ptr _VertexProgramBump1Diffuse; - static std::auto_ptr _VertexProgramBump2Diffuse; + static NLMISC::CSmartPtr _VertexProgramBump1Diffuse; + static NLMISC::CSmartPtr _VertexProgramBump2Diffuse; // - static std::auto_ptr _VertexProgramNoBump; - static std::auto_ptr _VertexProgramNoBumpDiffuse; + static NLMISC::CSmartPtr _VertexProgramNoBump; + static NLMISC::CSmartPtr _VertexProgramNoBumpDiffuse;*/ // - static std::auto_ptr _VertexProgramNoWave; - static std::auto_ptr _VertexProgramNoWaveDiffuse; + static NLMISC::CSmartPtr _VertexProgramNoWave; + static NLMISC::CSmartPtr _VertexProgramNoWaveDiffuse; }; diff --git a/code/nel/include/nel/georges/load_form.h b/code/nel/include/nel/georges/load_form.h index 6bf6c83c3..4aaab43d0 100644 --- a/code/nel/include/nel/georges/load_form.h +++ b/code/nel/include/nel/georges/load_form.h @@ -109,7 +109,7 @@ struct TLoadFormDicoEntry } }; */ -const uint32 PACKED_SHEET_HEADER = 'PKSH'; +const uint32 PACKED_SHEET_HEADER = NELID("PKSH"); const uint32 PACKED_SHEET_VERSION = 5; // This Version may be used if you want to use the serialVersion() system in loadForm() const uint32 PACKED_SHEET_VERSION_COMPATIBLE = 0; diff --git a/code/nel/include/nel/misc/fast_floor.h b/code/nel/include/nel/misc/fast_floor.h index f58e475e5..6cb8e209c 100644 --- a/code/nel/include/nel/misc/fast_floor.h +++ b/code/nel/include/nel/misc/fast_floor.h @@ -19,6 +19,7 @@ #include "types_nl.h" #include +#include namespace NLMISC { diff --git a/code/nel/include/nel/misc/stream.h b/code/nel/include/nel/misc/stream.h index ad0e8ddd4..5a342643d 100644 --- a/code/nel/include/nel/misc/stream.h +++ b/code/nel/include/nel/misc/stream.h @@ -53,6 +53,13 @@ class CMemStream; # endif # define NLMISC_BSWAP64(src) (src) = (((src)>>56)&0xFF) | ((((src)>>48)&0xFF)<<8) | ((((src)>>40)&0xFF)<<16) | ((((src)>>32)&0xFF)<<24) | ((((src)>>24)&0xFF)<<32) | ((((src)>>16)&0xFF)<<40) | ((((src)>>8)&0xFF)<<48) | (((src)&0xFF)<<56) +// convert a 4 characters string to uint32 +#ifdef NL_LITTLE_ENDIAN +# define NELID(x) (uint32((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | (x[3]))) +#else +# define NELID(x) (uint32((x[3] << 24) | (x[2] << 16) | (x[1] << 8) | (x[0]))) +#endif + // ====================================================================================================== /** * Stream Exception. diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index 86ea69076..100c3ab9b 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -136,8 +136,6 @@ SOURCE_GROUP(Driver FILES ../../include/nel/3d/dru.h event_mouse_listener.cpp ../../include/nel/3d/event_mouse_listener.h - ../../include/nel/3d/i_program.h - ../../include/nel/3d/i_program_object.h index_buffer.cpp ../../include/nel/3d/index_buffer.h init_3d.cpp @@ -146,10 +144,10 @@ SOURCE_GROUP(Driver FILES ../../include/nel/3d/light.h material.cpp ../../include/nel/3d/material.h - dynamic_material.cpp - ../../include/nel/3d/dynamic_material.h - dyn_mat_loader.cpp - ../../include/nel/3d/dyb_mat_loader.h + dynamic_material.cpp + ../../include/nel/3d/dynamic_material.h + dyn_mat_loader.cpp + ../../include/nel/3d/dyb_mat_loader.h nelu.cpp ../../include/nel/3d/nelu.h ../../include/nel/3d/occlusion_query.h @@ -161,15 +159,15 @@ SOURCE_GROUP(Driver FILES ../../include/nel/3d/scene_group.h shader.cpp ../../include/nel/3d/shader.h - shader_loader.cpp - ../../include/nel/3d/shader_loader.h - shader_manager.cpp - ../../include/nel/3d/shader_manager.h - shader_program.cpp - ../../include/nel/3d/shader_program.h - shader_saver.cpp - ../../include/nel/3d/shader_saver.h - ../../include/nel/3d/shader_visitor.h + shader_loader.cpp + ../../include/nel/3d/shader_loader.h + shader_manager.cpp + ../../include/nel/3d/shader_manager.h + shader_program.cpp + ../../include/nel/3d/shader_program.h + shader_saver.cpp + ../../include/nel/3d/shader_saver.h + ../../include/nel/3d/shader_visitor.h texture.cpp ../../include/nel/3d/texture.h vertex_buffer.cpp @@ -179,7 +177,15 @@ SOURCE_GROUP(Driver FILES vertex_program.cpp ../../include/nel/3d/vertex_program.h vertex_program_parse.cpp - ../../include/nel/3d/vertex_program_parse.h) + ../../include/nel/3d/vertex_program_parse.h + pixel_program.cpp + ../../include/nel/3d/pixel_program.h + geometry_program.cpp + ../../include/nel/3d/geometry_program.h + program.cpp + ../../include/nel/3d/program.h + gpu_program_params.cpp + ../../include/nel/3d/gpu_program_params.h) SOURCE_GROUP(Font FILES computed_string.cpp @@ -703,12 +709,24 @@ SOURCE_GROUP(Shadows FILES ../../include/nel/3d/shadow_map_manager.h shadow_poly_receiver.cpp ../../include/nel/3d/shadow_poly_receiver.h) +SOURCE_GROUP(Stereo FILES + stereo_display.cpp + ../../include/nel/3d/stereo_display.h + stereo_hmd.cpp + ../../include/nel/3d/stereo_hmd.h + stereo_ovr.cpp + stereo_ovr_fp.cpp + ../../include/nel/3d/stereo_ovr.h + stereo_libvr.cpp + ../../include/nel/3d/stereo_libvr.h + stereo_debugger.cpp + ../../include/nel/3d/stereo_debugger.h) NL_TARGET_LIB(nel3d ${HEADERS} ${SRC}) -INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIRS} ${LIBOVR_INCLUDE_DIR} ${LIBVR_INCLUDE_DIR}) -TARGET_LINK_LIBRARIES(nel3d nelmisc ${FREETYPE_LIBRARIES}) +TARGET_LINK_LIBRARIES(nel3d nelmisc ${FREETYPE_LIBRARIES} ${LIBOVR_LIBRARIES} ${LIBVR_LIBRARY}) SET_TARGET_PROPERTIES(nel3d PROPERTIES LINK_INTERFACE_LIBRARIES "") NL_DEFAULT_PROPS(nel3d "NeL, Library: NeL 3D") NL_ADD_RUNTIME_FLAGS(nel3d) @@ -718,6 +736,9 @@ NL_ADD_LIB_SUFFIX(nel3d) ADD_DEFINITIONS(${LIBXML2_DEFINITIONS}) +ADD_DEFINITIONS(${LIBOVR_DEFINITIONS}) +ADD_DEFINITIONS(${LIBVR_DEFINITIONS}) + IF(WITH_PCH) ADD_NATIVE_PRECOMPILED_HEADER(nel3d ${CMAKE_CURRENT_SOURCE_DIR}/std3d.h ${CMAKE_CURRENT_SOURCE_DIR}/std3d.cpp) ENDIF(WITH_PCH) diff --git a/code/nel/src/3d/animation.cpp b/code/nel/src/3d/animation.cpp index 9cfd3f26b..a604d2bde 100644 --- a/code/nel/src/3d/animation.cpp +++ b/code/nel/src/3d/animation.cpp @@ -89,8 +89,8 @@ void CAnimation::serial (NLMISC::IStream& f) nlassert(_IdByChannelId.empty()); // Serial a header - f.serialCheck ((uint32)'_LEN'); - f.serialCheck ((uint32)'MINA'); + f.serialCheck (NELID("_LEN")); + f.serialCheck (NELID("MINA")); // Serial a version sint version=f.serialVersion (2); diff --git a/code/nel/src/3d/animation_set.cpp b/code/nel/src/3d/animation_set.cpp index 94946799b..05db8a7be 100644 --- a/code/nel/src/3d/animation_set.cpp +++ b/code/nel/src/3d/animation_set.cpp @@ -185,9 +185,9 @@ void CAnimationSet::serial (NLMISC::IStream& f) nlassert(!_AnimHeaderOptimisation); // Serial an header - f.serialCheck ((uint32)'_LEN'); - f.serialCheck ((uint32)'MINA'); - f.serialCheck ((uint32)'TES_'); + f.serialCheck (NELID("_LEN")); + f.serialCheck (NELID("MINA")); + f.serialCheck (NELID("TES_")); // Serial a version uint ver= f.serialVersion (1); diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 7cbb48310..7809aba2c 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -55,13 +55,18 @@ static const char *TextureOffset = END \n"; -static CVertexProgram TextureOffsetVertexProgram(TextureOffset); +static NLMISC::CSmartPtr TextureOffsetVertexProgram; //----------------------------------------------------------------------------------------------------------- CBloomEffect::CBloomEffect() { + if (!TextureOffsetVertexProgram) + { + TextureOffsetVertexProgram = new CVertexProgram(TextureOffset); + } + _Driver = NULL; _Scene = NULL; _SquareBloom = true; @@ -285,6 +290,8 @@ void CBloomEffect::initBloom() // clientcfg if(!_Init) init(); + _OriginalRenderTarget = static_cast(_Driver)->getDriver()->getRenderTarget(); + // if window resize, reinitialize textures if(_WndWidth!=_Driver->getWindowWidth() || _WndHeight!=_Driver->getWindowHeight()) { @@ -349,13 +356,15 @@ void CBloomEffect::initBloom() // clientcfg } } - NL3D::CTextureUser *txt = (_InitBloomEffect) ? (new CTextureUser(_InitText)) : (new CTextureUser()); - if(!((CDriverUser *) _Driver)->setRenderTarget(*txt, 0, 0, _WndWidth, _WndHeight)) + if (!_OriginalRenderTarget) { - nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); - return; + NL3D::CTextureUser txt = (_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser()); + if(!(static_cast(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight))) + { + nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); + return; + } } - delete txt; } //----------------------------------------------------------------------------------------------------------- @@ -371,13 +380,13 @@ void CBloomEffect::endBloom() // clientcfg if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0) return; - CTextureUser *txt1 = (_InitBloomEffect) ? (new CTextureUser(_InitText)) : (new CTextureUser()); - CTextureUser *txt2 = new CTextureUser(_BlurFinalTex); - CRect *rect1 = new CRect(0, 0, _WndWidth, _WndHeight); - CRect *rect2 = new CRect(0, 0, _BlurWidth, _BlurHeight); + CTextureUser txt1 = _OriginalRenderTarget ? CTextureUser(_OriginalRenderTarget) : ((_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser())); + CTextureUser txt2(_BlurFinalTex); + CRect rect1(0, 0, _WndWidth, _WndHeight); + CRect rect2(0, 0, _BlurWidth, _BlurHeight); // stretch rect - ((CDriverUser *) _Driver)->stretchRect(_Scene, *txt1 , *rect1, - *txt2, *rect2); + ((CDriverUser *) _Driver)->stretchRect(_Scene, txt1 , rect1, + txt2, rect2); // horizontal blur pass doBlur(true); @@ -387,10 +396,6 @@ void CBloomEffect::endBloom() // clientcfg // apply blur with a blend operation applyBlur(); - delete txt1; - delete txt2; - delete rect1; - delete rect2; } //----------------------------------------------------------------------------------------------------------- @@ -399,16 +404,30 @@ void CBloomEffect::applyBlur() { NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); + /*if (_OriginalRenderTarget) + { + CTextureUser txt(_OriginalRenderTarget); + if(!(static_cast(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight))) + { + nlwarning("setRenderTarget return false with original render target for bloom effect\n"); + return; + } + } // in opengl, display in init texture - if(_InitBloomEffect) + else if(_InitBloomEffect) { - CTextureUser *txt = new CTextureUser(_InitText); - if(!((CDriverUser *) _Driver)->setRenderTarget(*txt, 0, 0, _WndWidth, _WndHeight)) + CTextureUser txt(_InitText); + if(!(static_cast(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight))) { nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); return; } - delete txt; + }*/ + CTextureUser txtApply = _OriginalRenderTarget ? CTextureUser(_OriginalRenderTarget) : ((_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser())); + if(!(static_cast(_Driver)->setRenderTarget(txtApply, 0, 0, _WndWidth, _WndHeight))) + { + nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); + return; } // display blur texture @@ -429,9 +448,9 @@ void CBloomEffect::applyBlur() } // initialize vertex program - drvInternal->activeVertexProgram(&TextureOffsetVertexProgram); - drvInternal->setConstant(8, 255.f, 255.f, 255.f, 255.f); - drvInternal->setConstant(9, 0.0f, 0.f, 0.f, 1.f); + drvInternal->activeVertexProgram(TextureOffsetVertexProgram); + drvInternal->setUniform4f(IDriver::VertexProgram, 8, 255.f, 255.f, 255.f, 255.f); + drvInternal->setUniform4f(IDriver::VertexProgram, 9, 0.0f, 0.f, 0.f, 1.f); // initialize blur material UMaterial displayBlurMat; @@ -463,7 +482,9 @@ void CBloomEffect::applyBlur() void CBloomEffect::endInterfacesDisplayBloom() // clientcfg { - if(_InitBloomEffect) + // Render from render target to screen if necessary. + // Don't do this when the blend was done to the screen or when rendering to a user provided rendertarget. + if ((_OriginalRenderTarget.getPtr() == NULL) && _InitBloomEffect) { if(!_Driver->supportBloomEffect() || !_Init) return; @@ -475,9 +496,8 @@ void CBloomEffect::endInterfacesDisplayBloom() // clientcfg return; NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); - CTextureUser *txt = new CTextureUser(); - ((CDriverUser *)_Driver)->setRenderTarget(*txt, 0, 0, 0, 0); - delete txt; + CTextureUser txtNull; + ((CDriverUser *)_Driver)->setRenderTarget(txtNull, 0, 0, 0, 0); // initialize texture coordinates float newU = drvInternal->isTextureRectangle(_InitText) ? (float)_WndWidth : 1.f; @@ -497,6 +517,8 @@ void CBloomEffect::endInterfacesDisplayBloom() // clientcfg _Driver->drawQuad(_DisplayQuad, _DisplayInitMat); _Driver->setMatrixMode3D(pCam); } + + _OriginalRenderTarget = NULL; } @@ -523,19 +545,18 @@ void CBloomEffect::doBlur(bool horizontalBlur) } NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); - CTextureUser *txt = new CTextureUser(endTexture); + CTextureUser txt(endTexture); // initialize render target - if(!((CDriverUser *) _Driver)->setRenderTarget(*txt, 0, 0, _BlurWidth, _BlurHeight)) + if(!((CDriverUser *) _Driver)->setRenderTarget(txt, 0, 0, _BlurWidth, _BlurHeight)) { nlwarning("setRenderTarget return false with blur texture for bloom effect\n"); return; } - delete txt; // initialize vertex program - drvInternal->activeVertexProgram(&TextureOffsetVertexProgram); - drvInternal->setConstant(8, 255.f, 255.f, 255.f, 255.f); - drvInternal->setConstant(9, 0.0f, 0.f, 0.f, 1.f); + drvInternal->activeVertexProgram(TextureOffsetVertexProgram); + drvInternal->setUniform4f(IDriver::VertexProgram, 8, 255.f, 255.f, 255.f, 255.f); + drvInternal->setUniform4f(IDriver::VertexProgram, 9, 0.0f, 0.f, 0.f, 1.f); // set several decal constants in order to obtain in the render target texture a mix of color // of a texel and its neighbored texels on the axe of the pass. @@ -554,10 +575,10 @@ void CBloomEffect::doBlur(bool horizontalBlur) decalR = 1.f; decal2R = 2.f; } - drvInternal->setConstant(10, (decalR/(float)_BlurWidth)*blurVec.x, (decalR/(float)_BlurHeight)*blurVec.y, 0.f, 0.f); - drvInternal->setConstant(11, (decal2R/(float)_BlurWidth)*blurVec.x, (decal2R/(float)_BlurHeight)*blurVec.y, 0.f, 0.f); - drvInternal->setConstant(12, (decalL/(float)_BlurWidth)*blurVec.x, (decalL/(float)_BlurHeight)*blurVec.y, 0.f, 0.f); - drvInternal->setConstant(13, (decal2L/(float)_BlurWidth)*blurVec.x, (decal2L/(float)_BlurHeight)*blurVec.y, 0.f, 0.f); + drvInternal->setUniform2f(IDriver::VertexProgram, 10, (decalR/(float)_BlurWidth)*blurVec.x, (decalR/(float)_BlurHeight)*blurVec.y); + drvInternal->setUniform2f(IDriver::VertexProgram, 11, (decal2R/(float)_BlurWidth)*blurVec.x, (decal2R/(float)_BlurHeight)*blurVec.y); + drvInternal->setUniform2f(IDriver::VertexProgram, 12, (decalL/(float)_BlurWidth)*blurVec.x, (decalL/(float)_BlurHeight)*blurVec.y); + drvInternal->setUniform2f(IDriver::VertexProgram, 13, (decal2L/(float)_BlurWidth)*blurVec.x, (decal2L/(float)_BlurHeight)*blurVec.y); // initialize material textures CMaterial * matObject = _BlurMat.getObjectPtr(); @@ -579,10 +600,9 @@ void CBloomEffect::doBlur(bool horizontalBlur) // disable render target and vertex program drvInternal->activeVertexProgram(NULL); - txt = new CTextureUser(); - ((CDriverUser *)_Driver)->setRenderTarget(*txt, 0, 0, 0, 0); + CTextureUser cu; + ((CDriverUser *)_Driver)->setRenderTarget(cu, 0, 0, 0, 0); _Driver->setMatrixMode3D(pCam); - delete txt; } }; // NL3D diff --git a/code/nel/src/3d/computed_string.cpp b/code/nel/src/3d/computed_string.cpp index a4c400284..a57191cc0 100644 --- a/code/nel/src/3d/computed_string.cpp +++ b/code/nel/src/3d/computed_string.cpp @@ -21,6 +21,7 @@ #include "nel/3d/index_buffer.h" #include "nel/3d/material.h" #include "nel/3d/frustum.h" +#include "nel/3d/viewport.h" #include "nel/misc/smart_ptr.h" #include "nel/misc/debug.h" @@ -85,6 +86,10 @@ void CComputedString::render2D (IDriver& driver, // get window size uint32 wndWidth, wndHeight; driver.getWindowSize(wndWidth, wndHeight); + CViewport vp; + driver.getViewport(vp); + wndWidth = (uint32)((float)wndWidth * vp.getWidth()); + wndHeight = (uint32)((float)wndHeight * vp.getHeight()); // scale to window size. x*= wndWidth; z*= wndHeight; diff --git a/code/nel/src/3d/driver.cpp b/code/nel/src/3d/driver.cpp index fa48649ae..2bfb0ea1f 100644 --- a/code/nel/src/3d/driver.cpp +++ b/code/nel/src/3d/driver.cpp @@ -20,7 +20,6 @@ #include "nel/misc/types_nl.h" #include "nel/3d/driver.h" -#include "nel/3d/shader.h" #include "nel/3d/vertex_buffer.h" #include "nel/misc/algo.h" @@ -33,7 +32,7 @@ namespace NL3D { // *************************************************************************** -const uint32 IDriver::InterfaceVersion = 0x6b; // added anisotropic filter +const uint32 IDriver::InterfaceVersion = 0x6d; // gpu program interface // *************************************************************************** IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" ) @@ -58,7 +57,7 @@ IDriver::~IDriver() nlassert(_MatDrvInfos.size()==0); nlassert(_VBDrvInfos.size()==0); nlassert(_IBDrvInfos.size()==0); - nlassert(_VtxPrgDrvInfos.size()==0); + nlassert(_GPUPrgDrvInfos.size()==0); } @@ -95,14 +94,6 @@ bool IDriver::release(void) delete *itmat; } - // Release Shader drv. - ItShaderDrvInfoPtrList itshd; - while( (itshd = _ShaderDrvInfos.begin()) != _ShaderDrvInfos.end() ) - { - // NB: at IShader deletion, this->_MatDrvInfos is updated (entry deleted); - delete *itshd; - } - // Release VBs drv. ItVBDrvInfoPtrList itvb; while( (itvb = _VBDrvInfos.begin()) != _VBDrvInfos.end() ) @@ -119,12 +110,12 @@ bool IDriver::release(void) delete *itib; } - // Release VtxPrg drv. - ItVtxPrgDrvInfoPtrList itVtxPrg; - while( (itVtxPrg = _VtxPrgDrvInfos.begin()) != _VtxPrgDrvInfos.end() ) + // Release GPUPrg drv. + ItGPUPrgDrvInfoPtrList itGPUPrg; + while( (itGPUPrg = _GPUPrgDrvInfos.begin()) != _GPUPrgDrvInfos.end() ) { - // NB: at IVertexProgramDrvInfos deletion, this->_VtxPrgDrvInfos is updated (entry deleted); - delete *itVtxPrg; + // NB: at IVertexProgramDrvInfos deletion, this->_GPUPrgDrvInfos is updated (entry deleted); + delete *itGPUPrg; } return true; @@ -249,14 +240,9 @@ void IDriver::removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt) _MatDrvInfos.erase(shaderIt); } // *************************************************************************** -void IDriver::removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt) -{ - _ShaderDrvInfos.erase(shaderIt); -} -// *************************************************************************** -void IDriver::removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt) +void IDriver::removeGPUPrgDrvInfoPtr(ItGPUPrgDrvInfoPtrList gpuPrgDrvInfoIt) { - _VtxPrgDrvInfos.erase(vtxPrgDrvInfoIt); + _GPUPrgDrvInfos.erase(gpuPrgDrvInfoIt); } // *************************************************************************** diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index 412cb52da..13306432f 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -193,6 +193,11 @@ CDriverD3D::CDriverD3D() #else // NL_DISABLE_HARDWARE_VERTEX_PROGAM _DisableHardwareVertexProgram = false; #endif // NL_DISABLE_HARDWARE_VERTEX_PROGAM +#ifdef NL_DISABLE_HARDWARE_PIXEL_PROGAM + _DisableHardwarePixelProgram = true; +#else // NL_DISABLE_HARDWARE_PIXEL_PROGAM + _DisableHardwarePixelProgram = false; +#endif // NL_DISABLE_HARDWARE_PIXEL_PROGAM #ifdef NL_DISABLE_HARDWARE_VERTEX_ARRAY_AGP _DisableHardwareVertexArrayAGP = true; #else // NL_DISABLE_HARDWARE_VERTEX_ARRAY_AGP @@ -1546,13 +1551,15 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r #endif // NL_FORCE_TEXTURE_STAGE_COUNT _VertexProgram = !_DisableHardwareVertexProgram && ((caps.VertexShaderVersion&0xffff) >= 0x0100); - _PixelShader = !_DisableHardwarePixelShader && (caps.PixelShaderVersion&0xffff) >= 0x0101; + _PixelProgramVersion = _DisableHardwareVertexProgram ? 0x0000 : caps.PixelShaderVersion & 0xffff; + nldebug("Pixel Program Version: %i.%i", (uint32)((_PixelProgramVersion & 0xFF00) >> 8), (uint32)(_PixelProgramVersion & 0xFF)); + _PixelProgram = _PixelProgramVersion >= 0x0101; _MaxVerticesByVertexBufferHard = caps.MaxVertexIndex; _MaxLight = caps.MaxActiveLights; if(_MaxLight > 0xFF) _MaxLight = 3; - if (_PixelShader) + if (_PixelProgram) { _MaxNumPerStageConstantLighted = _NbNeLTextureStages; _MaxNumPerStageConstantUnlighted = _NbNeLTextureStages; @@ -1703,6 +1710,13 @@ bool CDriverD3D::release() // Call IDriver::release() before, to destroy textures, shaders and VBs... IDriver::release(); + ItShaderDrvInfoPtrList itshd; + while( (itshd = _ShaderDrvInfos.begin()) != _ShaderDrvInfos.end() ) + { + // NB: at IShader deletion, this->_MatDrvInfos is updated (entry deleted); + delete *itshd; + } + _SwapBufferCounter = 0; if (_QuadIB) @@ -2016,6 +2030,8 @@ bool CDriverD3D::swapBuffers() // Reset vertex program setVertexProgram (NULL, NULL); + // Reset pixel program + setPixelShader (NULL); if (_VBHardProfiling) { @@ -2987,7 +3003,7 @@ bool CDriverD3D::stretchRect(ITexture * srcText, NLMISC::CRect &srcRect, ITextur bool CDriverD3D::supportBloomEffect() const { - return isVertexProgramSupported(); + return supportVertexProgram(CVertexProgram::nelvp); } // *************************************************************************** @@ -3330,9 +3346,9 @@ uint COcclusionQueryD3D::getVisibleCount() } // *************************************************************************** -bool CDriverD3D::isWaterShaderSupported() const +bool CDriverD3D::supportWaterShader() const { - H_AUTO_D3D(CDriverD3D_isWaterShaderSupported); + H_AUTO_D3D(CDriverD3D_supportWaterShader); return _PixelShaderVersion >= D3DPS_VERSION(1, 1); } @@ -3618,7 +3634,7 @@ void CDriverD3D::CVertexProgramPtrState::apply(CDriverD3D *driver) void CDriverD3D::CPixelShaderPtrState::apply(CDriverD3D *driver) { H_AUTO_D3D(CDriverD3D_CPixelShaderPtrState); - if (!driver->supportPixelShaders()) return; + if (!driver->_PixelProgram) return; driver->_DeviceInterface->SetPixelShader(PixelShader); } diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index cff7cb804..1055e105c 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -35,7 +35,6 @@ #include "nel/3d/scissor.h" #include "nel/3d/driver.h" #include "nel/3d/material.h" -#include "nel/3d/shader.h" #include "nel/3d/vertex_buffer.h" #include "nel/3d/index_buffer.h" #include "nel/3d/ptr_set.h" @@ -181,6 +180,75 @@ public: }; +using NLMISC::CRefCount; + + +class IDriver; +class CDriverD3D; + +// List typedef. +class IShaderDrvInfos; +typedef std::list TShaderDrvInfoPtrList; +typedef TShaderDrvInfoPtrList::iterator ItShaderDrvInfoPtrList; + +/** + * Interface for shader driver infos. + */ +class IShaderDrvInfos : public CRefCount +{ +private: + CDriverD3D *_Driver; + ItShaderDrvInfoPtrList _DriverIterator; + +public: + IShaderDrvInfos(CDriverD3D *drv, ItShaderDrvInfoPtrList it) {_Driver= drv; _DriverIterator= it;} + // The virtual dtor is important. + virtual ~IShaderDrvInfos(); +}; + + +/** + * Shader resource for the driver. It is just a container for a ".fx" text file. + */ +/* *** IMPORTANT ******************** + * *** IF YOU MODIFY THE STRUCTURE OF THIS CLASS, PLEASE INCREMENT IDriver::InterfaceVersion TO INVALIDATE OLD DRIVER DLL + * ********************************** + */ +// -------------------------------------------------- +class CD3DShaderFX +{ +public: + CD3DShaderFX(); + ~CD3DShaderFX(); + + // Load a shader file + bool loadShaderFile (const char *filename); + + // Set the shader text + void setText (const char *text); + + // Get the shader text + const char *getText () const { return _Text.c_str(); } + + // Set the shader name + void setName (const char *name); + + // Get the shader name + const char *getName () const { return _Name.c_str(); } + +public: + // Private. For Driver only. + bool _ShaderChanged; + NLMISC::CRefPtr _DrvInfo; +private: + // The shader + std::string _Text; + // The shader name + std::string _Name; +}; + + + // *************************************************************************** class CTextureDrvInfosD3D : public ITextureDrvInfos { @@ -229,16 +297,48 @@ public: }; + // *************************************************************************** -class CVertexProgamDrvInfosD3D : public IVertexProgramDrvInfos +class CVertexProgamDrvInfosD3D : public IProgramDrvInfos { public: // The shader IDirect3DVertexShader9 *Shader; - CVertexProgamDrvInfosD3D(IDriver *drv, ItVtxPrgDrvInfoPtrList it); + CVertexProgamDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it); ~CVertexProgamDrvInfosD3D(); + + virtual uint getUniformIndex(const char *name) const + { + std::map::const_iterator it = ParamIndices.find(name); + if (it != ParamIndices.end()) return it->second; + return ~0; + }; + + std::map ParamIndices; +}; + + +// *************************************************************************** +class CPixelProgramDrvInfosD3D : public IProgramDrvInfos +{ +public: + + // The shader + IDirect3DPixelShader9 *Shader; + + CPixelProgramDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it); + ~CPixelProgramDrvInfosD3D(); + + virtual uint getUniformIndex(const char *name) const + { + std::map::const_iterator it = ParamIndices.find(name); + if (it != ParamIndices.end()) return it->second; + return ~0; + }; + + std::map ParamIndices; }; @@ -333,7 +433,7 @@ public: // Scalar handles D3DXHANDLE ScalarFloatHandle[MaxShaderTexture]; - CShaderDrvInfosD3D(IDriver *drv, ItShaderDrvInfoPtrList it); + CShaderDrvInfosD3D(CDriverD3D *drv, ItShaderDrvInfoPtrList it); virtual ~CShaderDrvInfosD3D(); }; @@ -773,13 +873,13 @@ public: // Driver parameters virtual void disableHardwareVertexProgram(); + virtual void disableHardwarePixelProgram(); virtual void disableHardwareIndexArrayAGP(); virtual void disableHardwareVertexArrayAGP(); virtual void disableHardwareTextureShader(); virtual void forceDXTCCompression(bool dxtcComp); virtual void setAnisotropicFilter(sint filter); virtual void forceTextureResize(uint divisor); - virtual void forceNativeFragmentPrograms(bool /* nativeOnly */) {} // ignored // Driver information virtual uint getNumAdapter() const; @@ -841,6 +941,7 @@ public: // todo hulud d3d buffers virtual void getZBufferPart (std::vector &zbuffer, NLMISC::CRect &rect); virtual bool setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width, uint32 height, uint32 mipmapLevel, uint32 cubeFace); + virtual ITexture *getRenderTarget() const; virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y, uint32 width, uint32 height, uint32 mipmapLevel); virtual bool getRenderTargetSize (uint32 &width, uint32 &height); @@ -959,9 +1060,9 @@ public: virtual bool supportTextureShaders() const {return false;}; virtual bool supportMADOperator() const; // todo hulud d3d adressing mode - virtual bool isWaterShaderSupported() const; + virtual bool supportWaterShader() const; // todo hulud d3d adressing mode - virtual bool isTextureAddrModeSupported(CMaterial::TTexAddressingMode /* mode */) const {return false;}; + virtual bool supportTextureAddrMode(CMaterial::TTexAddressingMode /* mode */) const {return false;}; // todo hulud d3d adressing mode virtual void setMatrix2DForTextureOffsetAddrMode(const uint /* stage */, const float /* mat */[4]) {} @@ -991,18 +1092,133 @@ public: virtual void setupMaterialPass(uint pass); virtual void endMaterialMultiPass(); - // Vertex program - virtual bool isVertexProgramSupported () const; - virtual bool isVertexProgramEmulated () const; - virtual bool activeVertexProgram (CVertexProgram *program); - virtual void setConstant (uint index, float, float, float, float); - virtual void setConstant (uint index, double, double, double, double); - virtual void setConstant (uint index, const NLMISC::CVector& value); - virtual void setConstant (uint index, const NLMISC::CVectorD& value); - virtual void setConstant (uint index, uint num, const float *src); - virtual void setConstant (uint index, uint num, const double *src); - virtual void setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform); - virtual void setConstantFog (uint index); + + + + + + /// \name Vertex Program + // @{ + + // Order of preference + // - activeVertexProgram + // - CMaterial pass[n] VP (uses activeVertexProgram, but does not override if one already set by code) + // - default generic VP that mimics fixed pipeline / no VP with fixed pipeline + + /** + * Does the driver supports vertex program, but emulated by CPU ? + */ + virtual bool isVertexProgramEmulated() const; + + /** Return true if the driver supports the specified vertex program profile. + */ + virtual bool supportVertexProgram(CVertexProgram::TProfile profile) const; + + /** Compile the given vertex program, return if successful. + * If a vertex program was set active before compilation, + * the state of the active vertex program is undefined behaviour afterwards. + */ + virtual bool compileVertexProgram(CVertexProgram *program); + + /** Set the active vertex program. This will override vertex programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getVertexProgram returns NULL. + * The vertex program is activated immediately. + */ + virtual bool activeVertexProgram(CVertexProgram *program); + // @} + + + + /// \name Pixel Program + // @{ + + // Order of preference + // - activePixelProgram + // - CMaterial pass[n] PP (uses activePixelProgram, but does not override if one already set by code) + // - PP generated from CMaterial (uses activePixelProgram, but does not override if one already set by code) + + /** Return true if the driver supports the specified pixel program profile. + */ + virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const; + + /** Compile the given pixel program, return if successful. + * If a pixel program was set active before compilation, + * the state of the active pixel program is undefined behaviour afterwards. + */ + virtual bool compilePixelProgram(CPixelProgram *program); + + /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getPixelProgram returns NULL. + * The pixel program is activated immediately. + */ + virtual bool activePixelProgram(CPixelProgram *program); + // @} + + + + /// \name Geometry Program + // @{ + + // Order of preference + // - activeGeometryProgram + // - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code) + // - none + + /** Return true if the driver supports the specified pixel program profile. + */ + virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const { return false; } + + /** Compile the given pixel program, return if successful. + * If a pixel program was set active before compilation, + * the state of the active pixel program is undefined behaviour afterwards. + */ + virtual bool compileGeometryProgram(CGeometryProgram *program) { return false; } + + /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getGeometryProgram returns NULL. + * The pixel program is activated immediately. + */ + virtual bool activeGeometryProgram(CGeometryProgram *program) { return false; } + // @} + + + + /// \name Program parameters + // @{ + // Set parameters + virtual void setUniform1f(TProgram program, uint index, float f0); + virtual void setUniform2f(TProgram program, uint index, float f0, float f1); + virtual void setUniform3f(TProgram program, uint index, float f0, float f1, float f2); + virtual void setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3); + virtual void setUniform1i(TProgram program, uint index, sint32 i0); + virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1); + virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2); + virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3); + virtual void setUniform1ui(TProgram program, uint index, uint32 ui0); + virtual void setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1); + virtual void setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2); + virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3); + virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v); + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3); + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba); + virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m); + virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src); + virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src); + virtual void setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src); + // Set builtin parameters + virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform); + virtual void setUniformFog(TProgram program, uint index); + // Set feature parameters + virtual bool setUniformDriver(TProgram program); // set all driver-specific features params (based on program->features->DriverFlags) + virtual bool setUniformMaterial(TProgram program, CMaterial &material); // set all material-specific feature params (based on program->features->MaterialFlags) + virtual void setUniformParams(TProgram program, CGPUProgramParams ¶ms); // set all user-provided params from the storage + virtual bool isUniformProgramState() { return false; } + // @} + + + + + virtual void enableVertexProgramDoubleSidedColor(bool doubleSided); virtual bool supportVertexProgramDoubleSidedColor() const; @@ -1021,7 +1237,7 @@ public: * ColorOp[n] = DISABLE; * AlphaOp[n] = DISABLE; */ - virtual bool activeShader(CShader *shd); + bool activeShader(CD3DShaderFX *shd); // Bench virtual void startBench (bool wantStandardDeviation = false, bool quick = false, bool reset = true); @@ -1040,8 +1256,6 @@ public: uint32 getMaxVertexIndex() const { return _MaxVertexIndex; } - bool supportPixelShaders() const { return _PixelShader; } - // *** Inline info uint inlGetNumTextStages() const { return _NbNeLTextureStages; } @@ -1892,12 +2106,21 @@ public: return d3dtex; } + // Get the d3dtext mirror of an existing setuped pixel program. + static inline CPixelProgramDrvInfosD3D* getPixelProgramD3D(CPixelProgram& pixelProgram) + { + H_AUTO_D3D(CDriverD3D_getPixelProgramD3D); + CPixelProgramDrvInfosD3D* d3dPixelProgram; + d3dPixelProgram = (CPixelProgramDrvInfosD3D*)(IProgramDrvInfos*)(pixelProgram.m_DrvInfo); + return d3dPixelProgram; + } + // Get the d3dtext mirror of an existing setuped vertex program. static inline CVertexProgamDrvInfosD3D* getVertexProgramD3D(CVertexProgram& vertexProgram) { H_AUTO_D3D(CDriverD3D_getVertexProgramD3D); CVertexProgamDrvInfosD3D* d3dVertexProgram; - d3dVertexProgram = (CVertexProgamDrvInfosD3D*)(IVertexProgramDrvInfos*)(vertexProgram._DrvInfo); + d3dVertexProgram = (CVertexProgamDrvInfosD3D*)(IProgramDrvInfos*)(vertexProgram.m_DrvInfo); return d3dVertexProgram; } @@ -1943,7 +2166,7 @@ public: void releaseInternalShaders(); bool setShaderTexture (uint textureHandle, ITexture *texture, CFXCache *cache); - bool validateShader(CShader *shader); + bool validateShader(CD3DShaderFX *shader); void activePass (uint pass) { @@ -2080,6 +2303,8 @@ private: void findNearestFullscreenVideoMode(); + TShaderDrvInfoPtrList _ShaderDrvInfos; + // Windows std::string _WindowClass; HWND _HWnd; @@ -2197,8 +2422,10 @@ private: bool _ForceDXTCCompression:1; bool _TextureCubeSupported; bool _VertexProgram; - bool _PixelShader; + bool _PixelProgram; + uint16 _PixelProgramVersion; bool _DisableHardwareVertexProgram; + bool _DisableHardwarePixelProgram; bool _DisableHardwareVertexArrayAGP; bool _DisableHardwareIndexArrayAGP; bool _DisableHardwarePixelShader; @@ -2316,6 +2543,9 @@ private: // The last vertex buffer needs vertex color bool _FogEnabled; + NLMISC::CRefPtr _VertexProgramUser; + NLMISC::CRefPtr _PixelProgramUser; + // *** Internal resources // Current render pass @@ -2344,7 +2574,7 @@ private: CIndexBuffer _QuadIndexesAGP; // The last setuped shader - CShader *_CurrentShader; + CD3DShaderFX *_CurrentShader; UINT _CurrentShaderPassCount; public: struct CTextureRef @@ -2369,29 +2599,29 @@ private: CRenderVariable *_ModifiedRenderState; // Internal shaders - CShader _ShaderLightmap0; - CShader _ShaderLightmap1; - CShader _ShaderLightmap2; - CShader _ShaderLightmap3; - CShader _ShaderLightmap4; - CShader _ShaderLightmap0Blend; - CShader _ShaderLightmap1Blend; - CShader _ShaderLightmap2Blend; - CShader _ShaderLightmap3Blend; - CShader _ShaderLightmap4Blend; - CShader _ShaderLightmap0X2; - CShader _ShaderLightmap1X2; - CShader _ShaderLightmap2X2; - CShader _ShaderLightmap3X2; - CShader _ShaderLightmap4X2; - CShader _ShaderLightmap0BlendX2; - CShader _ShaderLightmap1BlendX2; - CShader _ShaderLightmap2BlendX2; - CShader _ShaderLightmap3BlendX2; - CShader _ShaderLightmap4BlendX2; - CShader _ShaderCloud; - CShader _ShaderWaterNoDiffuse; - CShader _ShaderWaterDiffuse; + CD3DShaderFX _ShaderLightmap0; + CD3DShaderFX _ShaderLightmap1; + CD3DShaderFX _ShaderLightmap2; + CD3DShaderFX _ShaderLightmap3; + CD3DShaderFX _ShaderLightmap4; + CD3DShaderFX _ShaderLightmap0Blend; + CD3DShaderFX _ShaderLightmap1Blend; + CD3DShaderFX _ShaderLightmap2Blend; + CD3DShaderFX _ShaderLightmap3Blend; + CD3DShaderFX _ShaderLightmap4Blend; + CD3DShaderFX _ShaderLightmap0X2; + CD3DShaderFX _ShaderLightmap1X2; + CD3DShaderFX _ShaderLightmap2X2; + CD3DShaderFX _ShaderLightmap3X2; + CD3DShaderFX _ShaderLightmap4X2; + CD3DShaderFX _ShaderLightmap0BlendX2; + CD3DShaderFX _ShaderLightmap1BlendX2; + CD3DShaderFX _ShaderLightmap2BlendX2; + CD3DShaderFX _ShaderLightmap3BlendX2; + CD3DShaderFX _ShaderLightmap4BlendX2; + CD3DShaderFX _ShaderCloud; + CD3DShaderFX _ShaderWaterNoDiffuse; + CD3DShaderFX _ShaderWaterDiffuse; // Backup frame buffer @@ -2527,6 +2757,10 @@ public: // Clip the wanted rectangle with window. return true if rect is not NULL. bool clipRect(NLMISC::CRect &rect); + friend class IShaderDrvInfos; + + void removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt); + }; #define NL_D3DCOLOR_RGBA(rgba) (D3DCOLOR_ARGB(rgba.A,rgba.R,rgba.G,rgba.B)) diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp index a7d218e79..40d01039b 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_material.cpp @@ -328,7 +328,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat) pShader = static_cast((IMaterialDrvInfos*)(mat._MatDrvInfo)); // Now we can get the supported shader from the cache. - CMaterial::TShader matShader = mat.getShader(); + CMaterial::TShader matShader = _PixelProgramUser ? CMaterial::Program : mat.getShader(); if (_CurrentMaterialSupportedShader != CMaterial::Normal) { @@ -567,7 +567,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat) normalShaderDesc.TexEnvMode[stage] = mat.getTexEnvMode(uint8(stage)); } - if (_PixelShader) + if (_PixelProgram) { #ifdef NL_DEBUG_D3D // Check, should not occured @@ -648,7 +648,9 @@ bool CDriverD3D::setupMaterial(CMaterial &mat) // Must separate texture setup and texture activation in 2 "for"... // because setupTexture() may disable all stage. - if (matShader == CMaterial::Normal) + if (matShader == CMaterial::Normal + || ((matShader == CMaterial::Program) && (_PixelProgramUser->features().MaterialFlags & CProgramFeatures::TextureStages)) + ) { uint stage; for(stage=0 ; stagefeatures().MaterialFlags & CProgramFeatures::TextureStages)) + ) { uint stage; for(stage=0 ; stageNeedsConstantForDiffuse && _PixelShader) + if (!pShader->NeedsConstantForDiffuse && _PixelProgram) setPixelShader (pShader->PixelShader); } break; @@ -2019,7 +2023,7 @@ void CDriverD3D::endMaterialMultiPass() bool CDriverD3D::supportCloudRenderSinglePass () const { H_AUTO_D3D(CDriver3D_supportCloudRenderSinglePass); - return _PixelShader; + return _PixelProgram; } // *************************************************************************** diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_pixel_program.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_pixel_program.cpp new file mode 100644 index 000000000..e0a2cd4a4 --- /dev/null +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_pixel_program.cpp @@ -0,0 +1,153 @@ +/** \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" + +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((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 diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp index b9b757de1..5cc6c283c 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_shader.cpp @@ -17,6 +17,8 @@ #include "stddirect3d.h" #include "driver_direct3d.h" +#include "nel/misc/path.h" +#include "nel/misc/file.h" using namespace std; using namespace NLMISC; @@ -24,6 +26,93 @@ using namespace NLMISC; namespace NL3D { + +// *************************************************************************** + +CD3DShaderFX::~CD3DShaderFX() +{ + // Must kill the drv mirror of this shader. + _DrvInfo.kill(); +} + +// *************************************************************************** + +CD3DShaderFX::CD3DShaderFX() +{ + _ShaderChanged = true; +} + +// *************************************************************************** + +void CD3DShaderFX::setText (const char *text) +{ + _Text = text; + _ShaderChanged = true; +} + +// *************************************************************************** + +void CD3DShaderFX::setName (const char *name) +{ + _Name = name; + _ShaderChanged = true; +} + +// *************************************************************************** + +bool CD3DShaderFX::loadShaderFile (const char *filename) +{ + _Text = ""; + // Lookup + string _filename = NLMISC::CPath::lookup(filename, false, true, true); + if (!_filename.empty()) + { + // File length + uint size = NLMISC::CFile::getFileSize (_filename); + _Text.reserve (size+1); + + try + { + NLMISC::CIFile file; + if (file.open (_filename)) + { + // Read it + while (!file.eof ()) + { + char line[512]; + file.getline (line, 512); + _Text += line; + } + + // Set the shader name + _Name = NLMISC::CFile::getFilename (filename); + return true; + } + else + { + nlwarning ("Can't open the file %s for reading", _filename.c_str()); + } + } + catch (const Exception &e) + { + nlwarning ("Error while reading %s : %s", _filename.c_str(), e.what()); + } + } + return false; +} + +// *************************************************************************** + +IShaderDrvInfos::~IShaderDrvInfos() +{ + _Driver->removeShaderDrvInfoPtr(_DriverIterator); +} + +void CDriverD3D::removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt) +{ + _ShaderDrvInfos.erase(shaderIt); +} + // mem allocator for state records std::allocator CStateRecord::Allocator; @@ -249,7 +338,7 @@ HRESULT CDriverD3D::SetVertexShaderConstantI(UINT StartRegister, CONST INT* pCon // *************************************************************************** -CShaderDrvInfosD3D::CShaderDrvInfosD3D(IDriver *drv, ItShaderDrvInfoPtrList it) : IShaderDrvInfos(drv, it) +CShaderDrvInfosD3D::CShaderDrvInfosD3D(CDriverD3D *drv, ItShaderDrvInfoPtrList it) : IShaderDrvInfos(drv, it) { H_AUTO_D3D(CShaderDrvInfosD3D_CShaderDrvInfosD3D) Validated = false; @@ -265,7 +354,7 @@ CShaderDrvInfosD3D::~CShaderDrvInfosD3D() // *************************************************************************** -bool CDriverD3D::validateShader(CShader *shader) +bool CDriverD3D::validateShader(CD3DShaderFX *shader) { H_AUTO_D3D(CDriverD3D_validateShader) CShaderDrvInfosD3D *shaderInfo = static_cast((IShaderDrvInfos*)shader->_DrvInfo); @@ -327,7 +416,7 @@ bool CDriverD3D::validateShader(CShader *shader) // *************************************************************************** -bool CDriverD3D::activeShader(CShader *shd) +bool CDriverD3D::activeShader(CD3DShaderFX *shd) { H_AUTO_D3D(CDriverD3D_activeShader) if (_DisableHardwarePixelShader) @@ -393,7 +482,7 @@ bool CDriverD3D::activeShader(CShader *shd) } -static void setFX(CShader &s, const char *name, const char *prog, CDriverD3D *drv) +static void setFX(CD3DShaderFX &s, const char *name, const char *prog, CDriverD3D *drv) { H_AUTO_D3D(setFX) diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp index 7922b30ea..87f41678b 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_texture.cpp @@ -1187,6 +1187,11 @@ bool CDriverD3D::setRenderTarget (ITexture *tex, uint32 /* x */, uint32 /* y */, return true; } +ITexture *CDriverD3D::getRenderTarget() const +{ + return _RenderTarget.Texture; +} + // *************************************************************************** bool CDriverD3D::copyTargetToTexture (ITexture * /* tex */, uint32 /* offsetx */, uint32 /* offsety */, uint32 /* x */, uint32 /* y */, uint32 /* width */, diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp new file mode 100644 index 000000000..e44780e89 --- /dev/null +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp @@ -0,0 +1,242 @@ +// NeL - MMORPG Framework +// 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 . + +#include "stddirect3d.h" + +#include "driver_direct3d.h" + +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 diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_vertex_program.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_vertex_program.cpp index ce6bda220..d4af02592 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_vertex_program.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_vertex_program.cpp @@ -26,7 +26,7 @@ namespace NL3D // *************************************************************************** -CVertexProgamDrvInfosD3D::CVertexProgamDrvInfosD3D(IDriver *drv, ItVtxPrgDrvInfoPtrList it) : IVertexProgramDrvInfos (drv, it) +CVertexProgamDrvInfosD3D::CVertexProgamDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it) : IProgramDrvInfos (drv, it) { H_AUTO_D3D(CVertexProgamDrvInfosD3D_CVertexProgamDrvInfosD3D) Shader = NULL; @@ -43,10 +43,10 @@ CVertexProgamDrvInfosD3D::~CVertexProgamDrvInfosD3D() // *************************************************************************** -bool CDriverD3D::isVertexProgramSupported () const +bool CDriverD3D::supportVertexProgram (CVertexProgram::TProfile profile) const { - H_AUTO_D3D(CDriverD3D_isVertexProgramSupported ) - return _VertexProgram; + H_AUTO_D3D(CDriverD3D_supportVertexProgram ) + return (profile == CVertexProgram::nelvp) && _VertexProgram; } // *************************************************************************** @@ -262,101 +262,130 @@ void dump(const CVPParser::TProgram &prg, std::string &dest) // *************************************************************************** -bool CDriverD3D::activeVertexProgram (CVertexProgram *program) +bool CDriverD3D::compileVertexProgram(NL3D::CVertexProgram *program) { - H_AUTO_D3D(CDriverD3D_activeVertexProgram ) - if (_DisableHardwareVertexProgram) - return false; - - // Setup or unsetup ? - if (program) + // Program setuped ? + if (program->m_DrvInfo == NULL) { - // Program setuped ? - if (program->_DrvInfo==NULL) + // Find nelvp + IProgram::CSource *source = NULL; + for (uint i = 0; i < program->getSourceNb(); ++i) { - _VtxPrgDrvInfos.push_front (NULL); - ItVtxPrgDrvInfoPtrList itTex = _VtxPrgDrvInfos.begin(); - *itTex = new CVertexProgamDrvInfosD3D(this, itTex); - - // Create a driver info structure - program->_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(program->getProgram().c_str(), parsedProgram, errorOutput); - if (!result) + if (program->getSource(i)->Profile == CVertexProgram::nelvp) { - nlwarning("Unable to parse a vertex program :"); - nlwarning(errorOutput.c_str()); - #ifdef NL_DEBUG_D3D - nlassert(0); - #endif // NL_DEBUG_D3D - return false; + 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) + // 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) { - for(uint l = 0; l < parsedProgram[k].getNumUsedSrc(); ++l) + const CVPOperand &op = parsedProgram[k].getSrc(l); + if (op.Type == CVPOperand::InputRegister) { - const CVPOperand &op = parsedProgram[k].getSrc(l); - if (op.Type == CVPOperand::InputRegister) - { - nlassert(op.Value.InputRegisterValue != CVPOperand::IWeight); - nlassert(op.Value.InputRegisterValue != CVPOperand::IPaletteSkin); - } + nlassert(op.Value.InputRegisterValue != CVPOperand::IWeight); + nlassert(op.Value.InputRegisterValue != CVPOperand::IPaletteSkin); } } - #endif + } + #endif - // Dump the vertex program - std::string dest; - dump(parsedProgram, dest); + // 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("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()); + 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) { - CVertexProgamDrvInfosD3D *info = static_cast((IVertexProgramDrvInfos*)program->_DrvInfo); + if (!CDriverD3D::compileVertexProgram(program)) return false; + + CVertexProgamDrvInfosD3D *info = NLMISC::safe_cast((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; @@ -366,6 +395,7 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program) else { setVertexProgram (NULL, NULL); + _VertexProgramUser = NULL; // Set the old fog range setRenderState (D3DRS_FOGSTART, *((DWORD*) (&_FogStart))); @@ -377,171 +407,6 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program) // *************************************************************************** -void CDriverD3D::setConstant (uint index, float f0, float f1, float f2, float f3) -{ - H_AUTO_D3D(CDriverD3D_setConstant ) - if (!_VertexProgram) - { - #ifdef NL_DEBUG - nlwarning("No vertex programs available!!"); - #endif - return; - } - const float tabl[4] = {f0, f1, f2, f3}; - setVertexProgramConstant (index, tabl); -} - -// *************************************************************************** - -void CDriverD3D::setConstant (uint index, double d0, double d1, double d2, double d3) -{ - H_AUTO_D3D(CDriverD3D_setConstant ) - if (!_VertexProgram) - { - #ifdef NL_DEBUG - nlwarning("No vertex programs available!!"); - #endif - return; - } - const float tabl[4] = {(float)d0, (float)d1, (float)d2, (float)d3}; - setVertexProgramConstant (index, tabl); -} - -// *************************************************************************** - -void CDriverD3D::setConstant (uint index, const NLMISC::CVector& value) -{ - H_AUTO_D3D(CDriverD3D_setConstant ) - if (!_VertexProgram) - { - #ifdef NL_DEBUG - nlwarning("No vertex programs available!!"); - #endif - return; - } - const float tabl[4] = {value.x, value.y, value.z, 0}; - setVertexProgramConstant (index, tabl); -} - -// *************************************************************************** - -void CDriverD3D::setConstant (uint index, const NLMISC::CVectorD& value) -{ - H_AUTO_D3D(CDriverD3D_setConstant ) - if (!_VertexProgram) - { - #ifdef NL_DEBUG - nlwarning("No vertex programs available!!"); - #endif - return; - } - const float tabl[4] = {(float)value.x, (float)value.y, (float)value.z, 0}; - setVertexProgramConstant (index, tabl); -} - -// *************************************************************************** - -void CDriverD3D::setConstant (uint index, uint num, const float *src) -{ - H_AUTO_D3D(CDriverD3D_setConstant ) - if (!_VertexProgram) - { - #ifdef NL_DEBUG - nlwarning("No vertex programs available!!"); - #endif - return; - } - uint i; - for (i=0; i_11, matPtr->_21, matPtr->_31, matPtr->_41); - setConstant (index+1, matPtr->_12, matPtr->_22, matPtr->_32, matPtr->_42); - setConstant (index+2, matPtr->_13, matPtr->_23, matPtr->_33, matPtr->_43); - setConstant (index+3, matPtr->_14, matPtr->_24, matPtr->_34, matPtr->_44); -} - -// *************************************************************************** - -void CDriverD3D::setConstantFog (uint index) -{ - H_AUTO_D3D(CDriverD3D_setConstantFog ) - /* "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; - setConstant (index, - _D3DModelView._13/delta, -_D3DModelView._23/delta, -_D3DModelView._33/delta, 1-(_D3DModelView._43-_FogStart)/delta); -} - -// *************************************************************************** - void CDriverD3D::enableVertexProgramDoubleSidedColor(bool /* doubleSided */) { H_AUTO_D3D(CDriverD3D_enableVertexProgramDoubleSidedColor) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 08b883e12..02617990d 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -263,8 +263,6 @@ CDriverGL::CDriverGL() _CurrentFogColor[2]= 0; _CurrentFogColor[3]= 0; - _RenderTargetFBO = false; - _LightSetupDirty= false; _ModelViewMatrixDirty= false; _RenderSetupDirty= false; @@ -482,6 +480,7 @@ bool CDriverGL::setupDisplay() } _VertexProgramEnabled= false; + _PixelProgramEnabled= false; _LastSetupGLArrayVertexProgram= false; // Init VertexArrayRange according to supported extenstion. @@ -690,7 +689,7 @@ bool CDriverGL::stretchRect(ITexture * /* srcText */, NLMISC::CRect &/* srcRect // *************************************************************************** bool CDriverGL::supportBloomEffect() const { - return (isVertexProgramSupported() && supportFrameBufferObject() && supportPackedDepthStencil() && supportTextureRectangle()); + return (supportVertexProgram(CVertexProgram::nelvp) && supportFrameBufferObject() && supportPackedDepthStencil() && supportTextureRectangle()); } // *************************************************************************** @@ -702,7 +701,7 @@ bool CDriverGL::supportNonPowerOfTwoTextures() const // *************************************************************************** bool CDriverGL::isTextureRectangle(ITexture * tex) const { - return (supportTextureRectangle() && tex->isBloomTexture() && tex->mipMapOff() + return (!supportNonPowerOfTwoTextures() && supportTextureRectangle() && tex->isBloomTexture() && tex->mipMapOff() && (!isPowerOf2(tex->getWidth()) || !isPowerOf2(tex->getHeight()))); } @@ -737,6 +736,12 @@ void CDriverGL::disableHardwareVertexProgram() _Extensions.DisableHardwareVertexProgram= true; } +void CDriverGL::disableHardwarePixelProgram() +{ + H_AUTO_OGL(CDriverGL_disableHardwarePixelProgram) + _Extensions.DisableHardwarePixelProgram= true; +} + // *************************************************************************** void CDriverGL::disableHardwareVertexArrayAGP() { @@ -854,6 +859,7 @@ bool CDriverGL::swapBuffers() // Reset texture shaders //resetTextureShaders(); activeVertexProgram(NULL); + activePixelProgram(NULL); #ifndef USE_OPENGLES /* Yoyo: must do this (GeForce bug ??) else weird results if end render with a VBHard. @@ -1400,6 +1406,7 @@ void CDriverGL::setupFog(float start, float end, CRGBA color) glFogfv(GL_FOG_COLOR, _CurrentFogColor); +#ifndef USE_OPENGLES /** Special : with vertex program, using the extension EXT_vertex_shader, fog is emulated using 1 more constant to scale result to [0, 1] */ if (_Extensions.EXTVertexShader && !_Extensions.NVVertexProgram && !_Extensions.ARBVertexProgram) @@ -1409,14 +1416,18 @@ void CDriverGL::setupFog(float start, float end, CRGBA color) // last constant is used to store fog information (fog must be rescaled to [0, 1], because of a driver bug) if (start != end) { - setConstant(_EVSNumConstant, 1.f / (start - end), - end / (start - end), 0, 0); + float datas[] = { 1.f / (start - end), - end / (start - end), 0, 0 }; + nglSetInvariantEXT(_EVSConstantHandle + _EVSNumConstant, GL_FLOAT, datas); } else { - setConstant(_EVSNumConstant, 0.f, 0, 0, 0); + float datas[] = { 0.f, 0, 0, 0 }; + nglSetInvariantEXT(_EVSConstantHandle + _EVSNumConstant, GL_FLOAT, datas); } } } +#endif + _FogStart = start; _FogEnd = end; } @@ -1535,9 +1546,9 @@ bool CDriverGL::supportTextureShaders() const } // *************************************************************************** -bool CDriverGL::isWaterShaderSupported() const +bool CDriverGL::supportWaterShader() const { - H_AUTO_OGL(CDriverGL_isWaterShaderSupported); + H_AUTO_OGL(CDriverGL_supportWaterShader); if(_Extensions.ARBFragmentProgram && ARBWaterShader[0] != 0) return true; @@ -1547,9 +1558,9 @@ bool CDriverGL::isWaterShaderSupported() const } // *************************************************************************** -bool CDriverGL::isTextureAddrModeSupported(CMaterial::TTexAddressingMode /* mode */) const +bool CDriverGL::supportTextureAddrMode(CMaterial::TTexAddressingMode /* mode */) const { - H_AUTO_OGL(CDriverGL_isTextureAddrModeSupported) + H_AUTO_OGL(CDriverGL_supportTextureAddrMode) if (_Extensions.NVTextureShader) { @@ -1987,12 +1998,6 @@ static void fetchPerturbedEnvMapR200() #endif } -// *************************************************************************** -void CDriverGL::forceNativeFragmentPrograms(bool nativeOnly) -{ - _ForceNativeFragmentPrograms = nativeOnly; -} - // *************************************************************************** void CDriverGL::initFragmentShaders() { @@ -2567,14 +2572,6 @@ CVertexBuffer::TVertexColorType CDriverGL::getVertexColorFormat() const return CVertexBuffer::TRGBA; } -// *************************************************************************** -bool CDriverGL::activeShader(CShader * /* shd */) -{ - H_AUTO_OGL(CDriverGL_activeShader) - - return false; -} - // *************************************************************************** void CDriverGL::startBench (bool wantStandardDeviation, bool quick, bool reset) { diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index ee6431dc4..57f73b0b6 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -49,7 +49,6 @@ #include "nel/3d/driver.h" #include "nel/3d/material.h" -#include "nel/3d/shader.h" #include "nel/3d/vertex_buffer.h" #include "nel/3d/ptr_set.h" #include "nel/3d/texture_cube.h" @@ -308,6 +307,7 @@ public: virtual bool init (uint windowIcon = 0, emptyProc exitFunc = 0); virtual void disableHardwareVertexProgram(); + virtual void disableHardwarePixelProgram(); virtual void disableHardwareVertexArrayAGP(); virtual void disableHardwareTextureShader(); @@ -370,8 +370,6 @@ public: virtual void forceTextureResize(uint divisor); - virtual void forceNativeFragmentPrograms(bool nativeOnly); - /// Setup texture env functions. Used by setupMaterial void setTextureEnvFunction(uint stage, CMaterial& mat); @@ -405,8 +403,6 @@ public: virtual CMatrix getViewMatrix() const; - virtual bool activeShader(CShader *shd); - virtual void forceNormalize(bool normalize) { _ForceNormalize= normalize; @@ -565,6 +561,8 @@ public: virtual bool setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width, uint32 height, uint32 mipmapLevel, uint32 cubeFace); + virtual ITexture *getRenderTarget() const; + virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y, uint32 width, uint32 height, uint32 mipmapLevel); @@ -602,9 +600,9 @@ public: // @{ virtual bool supportTextureShaders() const; - virtual bool isWaterShaderSupported() const; + virtual bool supportWaterShader() const; - virtual bool isTextureAddrModeSupported(CMaterial::TTexAddressingMode mode) const; + virtual bool supportTextureAddrMode(CMaterial::TTexAddressingMode mode) const; virtual void setMatrix2DForTextureOffsetAddrMode(const uint stage, const float mat[4]); // @} @@ -694,6 +692,7 @@ private: virtual class IVertexBufferHardGL *createVertexBufferHard(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb); friend class CTextureDrvInfosGL; friend class CVertexProgamDrvInfosGL; + friend class CPixelProgamDrvInfosGL; private: // Version of the driver. Not the interface version!! Increment when implementation of the driver change. @@ -889,7 +888,7 @@ private: // viewport before call to setRenderTarget, if BFO extension is supported CViewport _OldViewport; - bool _RenderTargetFBO; + CSmartPtr _RenderTargetFBO; // Num lights return by GL_MAX_LIGHTS @@ -1300,36 +1299,156 @@ private: // @} - /// \name Vertex program interface + + + + + /// \name Vertex Program // @{ - bool isVertexProgramSupported () const; - bool isVertexProgramEmulated () const; - bool activeVertexProgram (CVertexProgram *program); - void setConstant (uint index, float, float, float, float); - void setConstant (uint index, double, double, double, double); - void setConstant (uint indexStart, const NLMISC::CVector& value); - void setConstant (uint indexStart, const NLMISC::CVectorD& value); - void setConstant (uint index, uint num, const float *src); - void setConstant (uint index, uint num, const double *src); - void setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform); - void setConstantFog (uint index); - void enableVertexProgramDoubleSidedColor(bool doubleSided); - bool supportVertexProgramDoubleSidedColor() const; + // Order of preference + // - activeVertexProgram + // - CMaterial pass[n] VP (uses activeVertexProgram, but does not override if one already set by code) + // - default generic VP that mimics fixed pipeline / no VP with fixed pipeline - virtual bool supportMADOperator() const ; + /** + * Does the driver supports vertex program, but emulated by CPU ? + */ + virtual bool isVertexProgramEmulated() const; + /** Return true if the driver supports the specified vertex program profile. + */ + virtual bool supportVertexProgram(CVertexProgram::TProfile profile) const; + + /** Compile the given vertex program, return if successful. + * If a vertex program was set active before compilation, + * the state of the active vertex program is undefined behaviour afterwards. + */ + virtual bool compileVertexProgram(CVertexProgram *program); + + /** Set the active vertex program. This will override vertex programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getVertexProgram returns NULL. + * The vertex program is activated immediately. + */ + virtual bool activeVertexProgram(CVertexProgram *program); + // @} + + + + /// \name Pixel Program + // @{ + // Order of preference + // - activePixelProgram + // - CMaterial pass[n] PP (uses activePixelProgram, but does not override if one already set by code) + // - PP generated from CMaterial (uses activePixelProgram, but does not override if one already set by code) + + /** Return true if the driver supports the specified pixel program profile. + */ + virtual bool supportPixelProgram(CPixelProgram::TProfile profile = CPixelProgram::arbfp1) const; + + /** Compile the given pixel program, return if successful. + * If a pixel program was set active before compilation, + * the state of the active pixel program is undefined behaviour afterwards. + */ + virtual bool compilePixelProgram(CPixelProgram *program); + + /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getPixelProgram returns NULL. + * The pixel program is activated immediately. + */ + virtual bool activePixelProgram(CPixelProgram *program); + // @} + + + + /// \name Geometry Program + // @{ + + // Order of preference + // - activeGeometryProgram + // - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code) + // - none + + /** Return true if the driver supports the specified pixel program profile. + */ + virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const { return false; } + + /** Compile the given pixel program, return if successful. + * If a pixel program was set active before compilation, + * the state of the active pixel program is undefined behaviour afterwards. + */ + virtual bool compileGeometryProgram(CGeometryProgram *program) { return false; } + + /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls. + * Also used internally by setupMaterial(CMaterial) when getGeometryProgram returns NULL. + * The pixel program is activated immediately. + */ + virtual bool activeGeometryProgram(CGeometryProgram *program) { return false; } // @} + + + /// \name Program parameters + // @{ + // Set parameters + inline void setUniform4fInl(TProgram program, uint index, float f0, float f1, float f2, float f3); + inline void setUniform4fvInl(TProgram program, uint index, size_t num, const float *src); + virtual void setUniform1f(TProgram program, uint index, float f0); + virtual void setUniform2f(TProgram program, uint index, float f0, float f1); + virtual void setUniform3f(TProgram program, uint index, float f0, float f1, float f2); + virtual void setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3); + virtual void setUniform1i(TProgram program, uint index, sint32 i0); + virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1); + virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2); + virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3); + virtual void setUniform1ui(TProgram program, uint index, uint32 ui0); + virtual void setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1); + virtual void setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2); + virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3); + virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v); + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3); + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba); + virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m); + virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src); + virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src); + virtual void setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src); + // Set builtin parameters + virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform); + virtual void setUniformFog(TProgram program, uint index); + // Set feature parameters + virtual bool isUniformProgramState() { return false; } + // @} + + + + + + virtual void enableVertexProgramDoubleSidedColor(bool doubleSided); + virtual bool supportVertexProgramDoubleSidedColor() const; + + virtual bool supportMADOperator() const ; + + + /// \name Vertex program implementation // @{ bool activeNVVertexProgram (CVertexProgram *program); bool activeARBVertexProgram (CVertexProgram *program); bool activeEXTVertexShader (CVertexProgram *program); + + bool compileNVVertexProgram (CVertexProgram *program); + bool compileARBVertexProgram (CVertexProgram *program); + bool compileEXTVertexShader (CVertexProgram *program); //@} + /// \name Pixel program implementation + // @{ + bool activeARBPixelProgram (CPixelProgram *program); + bool setupPixelProgram (CPixelProgram *program, GLuint id/*, bool &specularWritten*/); + //@} + /// \fallback for material shaders // @{ @@ -1342,15 +1461,27 @@ private: // Don't use glIsEnabled, too slow. return _VertexProgramEnabled; } + + bool isPixelProgramEnabled () const + { + // Don't use glIsEnabled, too slow. + return _PixelProgramEnabled; + } // Track state of activeVertexProgram() bool _VertexProgramEnabled; + // Track state of activePixelProgram() + bool _PixelProgramEnabled; + // Say if last setupGlArrays() was a VertexProgram setup. bool _LastSetupGLArrayVertexProgram; // The last vertex program that was setupped NLMISC::CRefPtr _LastSetuppedVP; + // The last pixel program that was setupped + NLMISC::CRefPtr _LastSetuppedPP; + bool _ForceDXTCCompression; /// Divisor for textureResize (power). uint _ForceTextureResizePower; @@ -1496,7 +1627,7 @@ private: }; // *************************************************************************** -class CVertexProgamDrvInfosGL : public IVertexProgramDrvInfos +class CVertexProgamDrvInfosGL : public IProgramDrvInfos { public: // The GL Id. @@ -1517,7 +1648,36 @@ public: // The gl id is auto created here. - CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it); + CVertexProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it); + + virtual uint getUniformIndex(const char *name) const + { + std::map::const_iterator it = ParamIndices.find(name); + if (it != ParamIndices.end()) return it->second; + return ~0; + }; + + std::map ParamIndices; +}; + +// *************************************************************************** +class CPixelProgamDrvInfosGL : public IProgramDrvInfos +{ +public: + // The GL Id. + GLuint ID; + + // The gl id is auto created here. + CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it); + + virtual uint getUniformIndex(const char *name) const + { + std::map::const_iterator it = ParamIndices.find(name); + if (it != ParamIndices.end()) return it->second; + return ~0; + }; + + std::map ParamIndices; }; #ifdef NL_STATIC diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp index d38ff8f51..3b771e1c1 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp @@ -1225,6 +1225,15 @@ static bool setupARBFragmentProgram(const char *glext) return true; } +// ********************************* +static bool setupNVFragmentProgram2(const char *glext) +{ + H_AUTO_OGL(setupNVFragmentProgram2); + CHECK_EXT("GL_NV_fragment_program2"); + + return true; +} + // *************************************************************************** static bool setupARBVertexBufferObject(const char *glext) { @@ -1560,6 +1569,19 @@ void registerGlExtensions(CGlExtensions &ext) ext.EXTVertexShader = false; ext.ARBVertexProgram = false; } + + // Check pixel program + // Disable feature ??? + if (!ext.DisableHardwarePixelProgram) + { + ext.ARBFragmentProgram = setupARBFragmentProgram(glext); + ext.NVFragmentProgram2 = setupNVFragmentProgram2(glext); + } + else + { + ext.ARBFragmentProgram = false; + ext.NVFragmentProgram2 = false; + } ext.OESDrawTexture = setupOESDrawTexture(glext); ext.OESMapBuffer = setupOESMapBuffer(glext); @@ -1571,14 +1593,12 @@ void registerGlExtensions(CGlExtensions &ext) ext.NVTextureShader = setupNVTextureShader(glext); ext.ATIEnvMapBumpMap = setupATIEnvMapBumpMap(glext); ext.ATIFragmentShader = setupATIFragmentShader(glext); - ext.ARBFragmentProgram = setupARBFragmentProgram(glext); } else { ext.ATIEnvMapBumpMap = false; ext.NVTextureShader = false; ext.ATIFragmentShader = false; - ext.ARBFragmentProgram = false; } // For now, the only way to know if emulation, is to test some extension which exist only on GeForce3. diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_extension.h b/code/nel/src/3d/driver/opengl/driver_opengl_extension.h index 9d28a15ab..fe7738fd8 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_extension.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl_extension.h @@ -103,6 +103,9 @@ struct CGlExtensions bool ARBTextureNonPowerOfTwo; bool ARBMultisample; + // NV Pixel Programs + bool NVFragmentProgram2; + bool OESDrawTexture; bool OESMapBuffer; @@ -111,6 +114,7 @@ public: /// \name Disable Hardware feature. False by default. setuped by IDriver // @{ bool DisableHardwareVertexProgram; + bool DisableHardwarePixelProgram; bool DisableHardwareVertexArrayAGP; bool DisableHardwareTextureShader; // @} @@ -174,6 +178,7 @@ public: /// \name Disable Hardware feature. False by default. setuped by IDriver DisableHardwareVertexProgram= false; + DisableHardwarePixelProgram= false; DisableHardwareVertexArrayAGP= false; DisableHardwareTextureShader= false; } @@ -206,6 +211,7 @@ public: result += NVTextureShader ? "NVTextureShader " : ""; result += ATIFragmentShader ? "ATIFragmentShader " : ""; result += ARBFragmentProgram ? "ARBFragmentProgram " : ""; + result += NVFragmentProgram2 ? "NVFragmentProgram2 " : ""; result += ARBVertexProgram ? "ARBVertexProgram " : ""; result += NVVertexProgram ? "NVVertexProgram " : ""; result += EXTVertexShader ? "EXTVertexShader " : ""; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp index 6d9dbb247..ed43fe8c3 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_material.cpp @@ -283,14 +283,15 @@ void CDriverGL::setTextureShaders(const uint8 *addressingModes, const CSmartPtr< bool CDriverGL::setupMaterial(CMaterial& mat) { H_AUTO_OGL(CDriverGL_setupMaterial) - CShaderGL* pShader; - GLenum glenum = GL_ZERO; - uint32 touched = mat.getTouched(); - uint stage; // profile. _NbSetupMaterialCall++; + CMaterial::TShader matShader; + + CShaderGL* pShader; + GLenum glenum = GL_ZERO; + uint32 touched = mat.getTouched(); // 0. Retrieve/Create driver shader. //================================== @@ -359,9 +360,29 @@ bool CDriverGL::setupMaterial(CMaterial& mat) mat.clearTouched(0xFFFFFFFF); } - // Now we can get the supported shader from the cache. - CMaterial::TShader matShader = pShader->SupportedShader; + // 2b. User supplied pixel shader overrides material + //================================== + /*if (_VertexProgramEnabled) + { + if (!setUniformDriver(VertexProgram)) return false; + if (!setUniformMaterialInternal(VertexProgram, mat)) return false; + }*/ + if (_PixelProgramEnabled) + { + matShader = CMaterial::Program; + + // if (!setUniformDriver(PixelProgram)) return false; + // if (!setUniformMaterialInternal(PixelProgram, mat)) return false; + if (!_LastSetuppedPP) return false; + } + else + { + // Now we can get the supported shader from the cache. + matShader = pShader->SupportedShader; + } + // 2b. Update more shader state + //================================== // if the shader has changed since last time if(matShader != _CurrentMaterialSupportedShader) { @@ -382,9 +403,11 @@ bool CDriverGL::setupMaterial(CMaterial& mat) // Must setup textures each frame. (need to test if touched). // Must separate texture setup and texture activation in 2 "for"... // because setupTexture() may disable all stage. - if (matShader != CMaterial::Water) + if (matShader != CMaterial::Water + && ((matShader != CMaterial::Program) || (_LastSetuppedPP->features().MaterialFlags & CProgramFeatures::TextureStages)) + ) { - for(stage=0 ; stagefeatures().MaterialFlags & CProgramFeatures::TextureStages)) ) { - for(stage=0 ; stagefeatures().MaterialFlags & CProgramFeatures::TextureMatrices)) + ) { setupUserTextureMatrix(inlGetNumTextStages(), mat); } - else // deactivate texture matrix + else { disableUserTextureMatrix(); } @@ -1476,7 +1502,7 @@ CTextureCube *CDriverGL::getSpecularCubeMap(uint exp) { 1.f, 4.f, 8.f, 24.f, 48.f, 128.f, 256.f, 511.f }; - const uint numCubeMap = sizeof(expToCubeMap) / sizeof(float); + const uint numCubeMap = sizeof(cubeMapExp) / sizeof(float); static bool tableBuilt = false; if (!tableBuilt) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp new file mode 100644 index 000000000..899511a1b --- /dev/null +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -0,0 +1,251 @@ +/** \file driver_opengl_pixel_program.cpp + * OpenGL driver implementation for pixel program manipulation. + * + * $Id: driver_opengl_pixel_program.cpp,v 1.1.2.4 2007/07/09 15:29:00 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 "stdopengl.h" + +#include "driver_opengl.h" +#include "nel/3d/index_buffer.h" +#include "nel/3d/pixel_program.h" +#include + +// tmp +#include "nel/misc/file.h" + +using namespace std; +using namespace NLMISC; + +namespace NL3D +{ + +#ifdef NL_STATIC +#ifdef USE_OPENGLES +namespace NLDRIVERGLES { +#else +namespace NLDRIVERGL { +#endif +#endif + +// *************************************************************************** + +CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it) : IProgramDrvInfos (drv, it) +{ + H_AUTO_OGL(CPixelProgamDrvInfosGL_CPixelProgamDrvInfosGL) + +#ifndef USE_OPENGLES + // Extension must exist + nlassert(drv->_Extensions.ARBFragmentProgram); + + if (drv->_Extensions.ARBFragmentProgram) // ARB implementation + { + nglGenProgramsARB(1, &ID); + } +#endif +} + +// *************************************************************************** + +bool CDriverGL::supportPixelProgram(CPixelProgram::TProfile profile) const +{ + H_AUTO_OGL(CPixelProgamDrvInfosGL_supportPixelProgram_profile) + switch (profile) + { + case CPixelProgram::arbfp1: + return _Extensions.ARBFragmentProgram; + case CPixelProgram::fp40: + return _Extensions.NVFragmentProgram2; + } + return false; +} + +// *************************************************************************** + +bool CDriverGL::activePixelProgram(CPixelProgram *program) +{ + H_AUTO_OGL(CDriverGL_activePixelProgram) + + if (_Extensions.ARBFragmentProgram) + { + return activeARBPixelProgram(program); + } + + return false; +} + +// *************************************************************************** + +bool CDriverGL::compilePixelProgram(NL3D::CPixelProgram *program) +{ +#ifndef USE_OPENGLES + // Program setuped ? + if (program->m_DrvInfo == NULL) + { + glDisable(GL_FRAGMENT_PROGRAM_ARB); + _PixelProgramEnabled = false; + + // Insert into driver list. (so it is deleted when driver is deleted). + ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IProgramDrvInfos*)NULL); + + // Create a driver info + CPixelProgamDrvInfosGL *drvInfo; + *it = drvInfo = new CPixelProgamDrvInfosGL(this, it); + // Set the pointer + program->m_DrvInfo = drvInfo; + + if (!setupPixelProgram(program, drvInfo->ID)) + { + delete drvInfo; + program->m_DrvInfo = NULL; + _GPUPrgDrvInfos.erase(it); + return false; + } + } + + return true; +#else + return false; +#endif +} + +// *************************************************************************** + +bool CDriverGL::activeARBPixelProgram(CPixelProgram *program) +{ + H_AUTO_OGL(CDriverGL_activeARBPixelProgram) + +#ifndef USE_OPENGLES + // Setup or unsetup ? + if (program) + { + // Program setuped ? + if (!CDriverGL::compilePixelProgram(program)) return false; + + // Cast the driver info pointer + CPixelProgamDrvInfosGL *drvInfo = safe_cast((IProgramDrvInfos*)program->m_DrvInfo); + + glEnable(GL_FRAGMENT_PROGRAM_ARB); + _PixelProgramEnabled = true; + nglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, drvInfo->ID); + + _LastSetuppedPP = program; + } + else + { + glDisable(GL_FRAGMENT_PROGRAM_ARB); + _PixelProgramEnabled = false; + } + + return true; +#else + return false; +#endif +} + +// *************************************************************************** + +bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &specularWritten*/) +{ + H_AUTO_OGL(CDriverGL_setupARBPixelProgram); + +#ifndef USE_OPENGLES + CPixelProgamDrvInfosGL *drvInfo = static_cast((IProgramDrvInfos *)program->m_DrvInfo); + + // 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; + } + + // Compile the program + nglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, id); + glGetError(); + nglProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, source->SourceLen, source->SourcePtr); + GLenum err = glGetError(); + if (err != GL_NO_ERROR) + { + if (err == GL_INVALID_OPERATION) + { + GLint position; + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &position); + nlassert(position != -1); // there was an error.. + nlassert(position < (GLint) source->SourceLen); + uint line = 0; + const char *lineStart = source->SourcePtr; + for(uint k = 0; k < (uint) position; ++k) + { + if (source->SourcePtr[k] == '\n') + { + lineStart = source->SourcePtr + k; + ++line; + } + } + nlwarning("ARB fragment program parse error at line %d.", (int) line); + // search end of line + const char *lineEnd = source->SourcePtr + source->SourceLen; + for(uint k = position; k < source->SourceLen; ++k) + { + if (source->SourcePtr[k] == '\n') + { + lineEnd = source->SourcePtr + k; + break; + } + } + nlwarning(std::string(lineStart, lineEnd).c_str()); + // display the gl error msg + const GLubyte *errorMsg = glGetString(GL_PROGRAM_ERROR_STRING_ARB); + nlassert((const char *) errorMsg); + nlwarning((const char *) errorMsg); + } + nlassert(0); + return false; + } + + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; + + // Build the feature info + program->buildInfo(source); + + return true; +#else + return false; +#endif +} + +#ifdef NL_STATIC +} // NLDRIVERGL/ES +#endif + +} // NL3D diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp index 055f8d99d..96d95bd5d 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_texture.cpp @@ -2323,7 +2323,7 @@ bool CDriverGL::setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width newVP.init(0, 0, ((float)width/(float)w), ((float)height/(float)h)); setupViewport(newVP); - _RenderTargetFBO = true; + _RenderTargetFBO = tex; return activeFrameBufferObject(tex); } @@ -2343,7 +2343,7 @@ bool CDriverGL::setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width setupViewport(_OldViewport); _OldViewport = _CurrViewport; - _RenderTargetFBO = false; + _RenderTargetFBO = NULL; return false; } @@ -2356,12 +2356,17 @@ bool CDriverGL::setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width // Update the scissor setupScissor (_CurrScissor); - _RenderTargetFBO = false; + _RenderTargetFBO = NULL; _OldViewport = _CurrViewport; return true; } +ITexture *CDriverGL::getRenderTarget() const +{ + return _RenderTargetFBO ? _RenderTargetFBO : _TextureTarget; +} + // *************************************************************************** bool CDriverGL::copyTargetToTexture (ITexture *tex, diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp new file mode 100644 index 000000000..9b0447dc5 --- /dev/null +++ b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp @@ -0,0 +1,509 @@ +// NeL - MMORPG Framework +// 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 . + +#include "stdopengl.h" + +#include "driver_opengl.h" + +using namespace std; +using namespace NLMISC; + +namespace NL3D { + +#ifdef NL_STATIC +#ifdef USE_OPENGLES +namespace NLDRIVERGLES { +#else +namespace NLDRIVERGL { +#endif +#endif + +inline void CDriverGL::setUniform4fInl(TProgram program, uint index, float f0, float f1, float f2, float f3) +{ + H_AUTO_OGL(CDriverGL_setUniform4f); + +#ifndef USE_OPENGLES + switch (program) + { + case VertexProgram: + if (_Extensions.NVVertexProgram) + { + // Setup constant + nglProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, index, f0, f1, f2, f3); + } + else if (_Extensions.ARBVertexProgram) + { + nglProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, index, f0, f1, f2, f3); + } + else if (_Extensions.EXTVertexShader) + { + float datas[] = { f0, f1, f2, f3 }; + nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, datas); + } + break; + case PixelProgram: + if (_Extensions.ARBFragmentProgram) + { + nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, f0, f1, f2, f3); + } + break; + } +#endif +} + +inline void CDriverGL::setUniform4fvInl(TProgram program, uint index, size_t num, const float *src) +{ + H_AUTO_OGL(CDriverGL_setUniform4fv); + +#ifndef USE_OPENGLES + switch (program) + { + case VertexProgram: + if (_Extensions.NVVertexProgram) + { + nglProgramParameters4fvNV(GL_VERTEX_PROGRAM_NV, index, num, src); + } + else if (_Extensions.ARBVertexProgram) // ARB pixel and geometry program will only exist when ARB vertex program exists + { + for (uint k = 0; k < num; ++k) + { + nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + k, src + 4 * k); + } + } + else if (_Extensions.EXTVertexShader) + { + for (uint k = 0; k < num; ++k) + { + nglSetInvariantEXT(_EVSConstantHandle + index + k, GL_FLOAT, (void *)(src + 4 * k)); + } + } + break; + case PixelProgram: + if (_Extensions.ARBFragmentProgram) // ARB pixel and geometry program will only exist when ARB vertex program exists + { + for (uint k = 0; k < num; ++k) + { + nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k); + } + } + break; + } +#endif +} + +void CDriverGL::setUniform1f(TProgram program, uint index, float f0) +{ + CDriverGL::setUniform4fInl(program, index, f0, 0.f, 0.f, 0.f); +} + +void CDriverGL::setUniform2f(TProgram program, uint index, float f0, float f1) +{ + CDriverGL::setUniform4fInl(program, index, f0, f1, 0.f, 0.f); +} + +void CDriverGL::setUniform3f(TProgram program, uint index, float f0, float f1, float f2) +{ + CDriverGL::setUniform4fInl(program, index, f0, f1, f2, 0.0f); +} + +void CDriverGL::setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3) +{ + CDriverGL::setUniform4fInl(program, index, f0, f1, f2, f3); +} + +void CDriverGL::setUniform1i(TProgram program, uint index, sint32 i0) +{ + +} + +void CDriverGL::setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1) +{ + +} + +void CDriverGL::setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2) +{ + +} + +void CDriverGL::setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) +{ + +} + +void CDriverGL::setUniform1ui(TProgram program, uint index, uint32 ui0) +{ + +} + +void CDriverGL::setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1) +{ + +} + +void CDriverGL::setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2) +{ + +} + +void CDriverGL::setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) +{ + +} + +void CDriverGL::setUniform3f(TProgram program, uint index, const NLMISC::CVector& v) +{ + CDriverGL::setUniform4fInl(program, index, v.x, v.y, v.z, 0.f); +} + +void CDriverGL::setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3) +{ + CDriverGL::setUniform4fInl(program, index, v.x, v.y, v.z, f3); +} + +void CDriverGL::setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba) +{ + CDriverGL::setUniform4fvInl(program, index, 1, &rgba.R); +} + +void CDriverGL::setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) +{ + H_AUTO_OGL(CDriverGL_setUniform4x4f); + + // TODO: Verify this! + NLMISC::CMatrix mat = m; + mat.transpose(); + const float *md = mat.get(); + + CDriverGL::setUniform4fvInl(program, index, 4, md); +} + +void CDriverGL::setUniform4fv(TProgram program, uint index, size_t num, const float *src) +{ + CDriverGL::setUniform4fvInl(program, index, num, src); +} + +void CDriverGL::setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src) +{ + +} + +void CDriverGL::setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src) +{ + +} + +const uint CDriverGL::GLMatrix[IDriver::NumMatrix]= +{ + GL_MODELVIEW, + GL_PROJECTION, +#ifdef USE_OPENGLES + GL_MODELVIEW +#else + GL_MODELVIEW_PROJECTION_NV +#endif +}; + +const uint CDriverGL::GLTransform[IDriver::NumTransform]= +{ +#ifdef USE_OPENGLES + 0, + 0, + 0, + 0 +#else + GL_IDENTITY_NV, + GL_INVERSE_NV, + GL_TRANSPOSE_NV, + GL_INVERSE_TRANSPOSE_NV +#endif +}; + +void CDriverGL::setUniformMatrix(NL3D::IDriver::TProgram program, uint index, NL3D::IDriver::TMatrix matrix, NL3D::IDriver::TTransform transform) +{ + H_AUTO_OGL(CDriverGL_setUniformMatrix); + +#ifndef USE_OPENGLES + // Vertex program exist ? + if (program == VertexProgram && _Extensions.NVVertexProgram) + { + // First, ensure that the render setup is correclty setuped. + refreshRenderSetup(); + + // Track the matrix + nglTrackMatrixNV(GL_VERTEX_PROGRAM_NV, index, GLMatrix[matrix], GLTransform[transform]); + // Release Track => matrix data is copied. + nglTrackMatrixNV(GL_VERTEX_PROGRAM_NV, index, GL_NONE, GL_IDENTITY_NV); + } + else + { + // First, ensure that the render setup is correctly setuped. + refreshRenderSetup(); + + CMatrix mat; + switch (matrix) + { + case IDriver::ModelView: + mat = _ModelViewMatrix; + break; + case IDriver::Projection: + { + refreshProjMatrixFromGL(); + mat = _GLProjMat; + } + break; + case IDriver::ModelViewProjection: + refreshProjMatrixFromGL(); + mat = _GLProjMat * _ModelViewMatrix; + break; + default: + break; + } + + switch(transform) + { + case IDriver::Identity: break; + case IDriver::Inverse: + mat.invert(); + break; + case IDriver::Transpose: + mat.transpose(); + break; + case IDriver::InverseTranspose: + mat.invert(); + mat.transpose(); + break; + default: + break; + } + + mat.transpose(); + const float *md = mat.get(); + + CDriverGL::setUniform4fvInl(program, index, 4, md); + } +#endif +} + +void CDriverGL::setUniformFog(NL3D::IDriver::TProgram program, uint index) +{ + H_AUTO_OGL(CDriverGL_setUniformFog) + + const float *values = _ModelViewMatrix.get(); + CDriverGL::setUniform4fInl(program, index, -values[2], -values[6], -values[10], -values[14]); +} + +/* + +bool CDriverGL::setUniformDriver(TProgram program) +{ + IProgram *prog = NULL; + switch (program) + { + case VertexProgram: + prog = _LastSetuppedVP; + break; + case PixelProgram: + prog = _LastSetuppedPP; + break; + } + if (!prog) return false; + + const CProgramFeatures &features = prog->features(); + + if (features.DriverFlags) + { + if (features.DriverFlags & CProgramFeatures::Matrices) + { + if (prog->getUniformIndex(CProgramIndex::ModelView) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CProgramIndex::ModelView), ModelView, Identity); + } + if (prog->getUniformIndex(CProgramIndex::ModelViewInverse) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CProgramIndex::ModelViewInverse), ModelView, Inverse); + } + if (prog->getUniformIndex(CProgramIndex::ModelViewTranspose) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CProgramIndex::ModelViewTranspose), ModelView, Transpose); + } + if (prog->getUniformIndex(CProgramIndex::ModelViewInverseTranspose) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CProgramIndex::ModelViewInverseTranspose), ModelView, InverseTranspose); + } + if (prog->getUniformIndex(CProgramIndex::Projection) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CProgramIndex::Projection), Projection, Identity); + } + if (prog->getUniformIndex(CProgramIndex::ProjectionInverse) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CProgramIndex::ProjectionInverse), Projection, Inverse); + } + if (prog->getUniformIndex(CProgramIndex::ProjectionTranspose) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CProgramIndex::ProjectionTranspose), Projection, Transpose); + } + if (prog->getUniformIndex(CProgramIndex::ProjectionInverseTranspose) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CProgramIndex::ProjectionInverseTranspose), Projection, InverseTranspose); + } + if (prog->getUniformIndex(CProgramIndex::ModelViewProjection) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CProgramIndex::ModelViewProjection), ModelViewProjection, Identity); + } + if (prog->getUniformIndex(CProgramIndex::ModelViewProjectionInverse) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CProgramIndex::ModelViewProjectionInverse), ModelViewProjection, Inverse); + } + if (prog->getUniformIndex(CProgramIndex::ModelViewProjectionTranspose) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CProgramIndex::ModelViewProjectionTranspose), ModelViewProjection, Transpose); + } + if (prog->getUniformIndex(CProgramIndex::ModelViewProjectionInverseTranspose) != ~0) + { + setUniformMatrix(program, prog->getUniformIndex(CProgramIndex::ModelViewProjectionInverseTranspose), ModelViewProjection, InverseTranspose); + } + } + if (features.DriverFlags & CProgramFeatures::Fog) + { + if (prog->getUniformIndex(CProgramIndex::Fog) != ~0) + { + setUniformFog(program, prog->getUniformIndex(CProgramIndex::Fog)); + } + } + } + + return true; +} + +bool CDriverGL::setUniformMaterial(TProgram program, CMaterial &material) +{ + IProgram *prog = NULL; + switch (program) + { + case VertexProgram: + prog = _LastSetuppedVP; + break; + case PixelProgram: + prog = _LastSetuppedPP; + break; + } + if (!prog) return false; + + const CProgramFeatures &features = prog->features(); + + // These are also already set by setupMaterial, so setupMaterial uses setUniformMaterialInternal instead + if (features.MaterialFlags & (CProgramFeatures::TextureStages | CProgramFeatures::TextureMatrices)) + { + if (features.MaterialFlags & CProgramFeatures::TextureStages) + { + for (uint stage = 0; stage < inlGetNumTextStages(); ++stage) + { + ITexture *text= material.getTexture(uint8(stage)); + + // Must setup textures each frame. (need to test if touched). + if (text != NULL && !setupTexture(*text)) + return false; + + // activate the texture, or disable texturing if NULL. + activateTexture(stage, text); + + // If texture not NULL, Change texture env function. + setTextureEnvFunction(stage, material); + } + + + } + if (features.MaterialFlags & CProgramFeatures::TextureMatrices) + { + // Textures user matrix + setupUserTextureMatrix(inlGetNumTextStages(), material); + } + } + + return true; +} + +bool CDriverGL::setUniformMaterialInternal(TProgram program, CMaterial &material) +{ + IProgram *prog = NULL; + switch (program) + { + case VertexProgram: + prog = _LastSetuppedVP; + break; + case PixelProgram: + prog = _LastSetuppedPP; + break; + } + if (!prog) return false; + + const CProgramFeatures &features = prog->features(); + + if (features.MaterialFlags & ~(CProgramFeatures::TextureStages | CProgramFeatures::TextureMatrices)) + { + // none + } + + return true; +} + +void CDriverGL::setUniformParams(TProgram program, CGPUProgramParams ¶ms) +{ + IProgram *prog = NULL; + switch (program) + { + case VertexProgram: + prog = _LastSetuppedVP; + break; + case PixelProgram: + prog = _LastSetuppedPP; + break; + } + if (!prog) return; + + size_t offset = params.getBegin(); + while (offset != params.getEnd()) + { + uint size = params.getSizeByOffset(offset); + uint count = params.getCountByOffset(offset); + + nlassert(size == 4 || count == 1); // only support float4 arrays + nlassert(params.getTypeByOffset(offset) == CGPUProgramParams::Float); // only support float + + uint index = params.getIndexByOffset(offset); + if (index == ~0) + { + const std::string &name = params.getNameByOffset(offset); + nlassert(!name.empty() /* missing both parameter name and index, code error /); + uint index = prog->getUniformIndex(name.c_str()); + nlassert(index != ~0 /* invalid parameter name /); + params.map(index, name); + } + + setUniform4fv(program, index, count, params.getPtrFByOffset(offset)); + + offset = params.getNext(offset); + } +} + +*/ + +#ifdef NL_STATIC +} // NLDRIVERGL/ES +#endif + +} // NL3D diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp index 14ed83adb..6df62dfc3 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp @@ -1151,7 +1151,7 @@ void CDriverGL::toggleGlArraysForEXTVertexShader() CVertexProgram *vp = _LastSetuppedVP; if (vp) { - CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IVertexProgramDrvInfos *) vp->_DrvInfo); + CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IProgramDrvInfos *) vp->m_DrvInfo); if (drvInfo) { // Disable all VertexAttribs. @@ -1396,7 +1396,7 @@ void CDriverGL::setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb) CVertexProgram *vp = _LastSetuppedVP; if (!vp) return; - CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IVertexProgramDrvInfos *) vp->_DrvInfo); + CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IProgramDrvInfos *) vp->m_DrvInfo); if (!drvInfo) return; uint32 flags= vb.VertexFormat; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp index 5392bcbdd..5470ec5c5 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp @@ -41,7 +41,7 @@ namespace NLDRIVERGL { #endif // *************************************************************************** -CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it) : IVertexProgramDrvInfos (drv, it) +CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL(CDriverGL *drv, ItGPUPrgDrvInfoPtrList it) : IProgramDrvInfos (drv, it) { H_AUTO_OGL(CVertexProgamDrvInfosGL_CVertexProgamDrvInfosGL); @@ -70,123 +70,153 @@ CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInf // *************************************************************************** -bool CDriverGL::isVertexProgramSupported () const +bool CDriverGL::supportVertexProgram(CVertexProgram::TProfile profile) const { - H_AUTO_OGL(CVertexProgamDrvInfosGL_isVertexProgramSupported) - return _Extensions.NVVertexProgram || _Extensions.EXTVertexShader || _Extensions.ARBVertexProgram; + H_AUTO_OGL(CVertexProgamDrvInfosGL_supportVertexProgram) + return (profile == CVertexProgram::nelvp) + && (_Extensions.NVVertexProgram || _Extensions.EXTVertexShader || _Extensions.ARBVertexProgram); } // *************************************************************************** -bool CDriverGL::isVertexProgramEmulated () const +bool CDriverGL::isVertexProgramEmulated() const { H_AUTO_OGL(CVertexProgamDrvInfosGL_isVertexProgramEmulated) return _Extensions.NVVertexProgramEmulated; } - - -// *************************************************************************** -bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) +bool CDriverGL::compileNVVertexProgram(CVertexProgram *program) { - H_AUTO_OGL(CVertexProgamDrvInfosGL_activeNVVertexProgram); + H_AUTO_OGL(CDriverGL_compileNVVertexProgram); #ifndef USE_OPENGLES - // Setup or unsetup ? - if (program) + + // Driver info + CVertexProgamDrvInfosGL *drvInfo; + + nlassert(!program->m_DrvInfo); + glDisable(GL_VERTEX_PROGRAM_NV); + _VertexProgramEnabled = false; + + // Find nelvp + IProgram::CSource *source = NULL; + for (uint i = 0; i < program->getSourceNb(); ++i) { - // Enable vertex program - glEnable (GL_VERTEX_PROGRAM_NV); - _VertexProgramEnabled= true; + if (program->getSource(i)->Profile == CVertexProgram::nelvp) + { + source = program->getSource(i); + } + } + if (!source) + { + nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used"); + return false; + } + /** 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 + nlassert(0); + #endif + return false; + } - // Driver info - CVertexProgamDrvInfosGL *drvInfo; + // Insert into driver list. (so it is deleted when driver is deleted). + ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IProgramDrvInfos*)NULL); - // Program setuped ? - if (program->_DrvInfo==NULL) + // Create a driver info + *it = drvInfo = new CVertexProgamDrvInfosGL(this, it); + + // Set the pointer + program->m_DrvInfo = drvInfo; + + // Compile the program + nglLoadProgramNV(GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)source->SourceLen, (const GLubyte*)source->SourcePtr); + + // Get loading error code + GLint errorOff; + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_NV, &errorOff); + + // Compilation error ? + if (errorOff >= 0) + { + // String length + uint length = (uint)source->SourceLen; + const char* sString = source->SourcePtr; + + // Line count and char count + uint line=1; + uint charC=1; + + // Find the line + uint offset=0; + while ((offset < length) && (offset < (uint)errorOff)) { - /** 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(program->getProgram().c_str(), parsedProgram, errorOutput); - if (!result) + if (sString[offset]=='\n') { - nlwarning("Unable to parse a vertex program :"); - nlwarning(errorOutput.c_str()); - #ifdef NL_DEBUG - nlassert(0); - #endif - return false; + line++; + charC=1; } + else + charC++; - // Insert into driver list. (so it is deleted when driver is deleted). - ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL); - - // Create a driver info - *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); + // Next character + offset++; + } - // Set the pointer - program->_DrvInfo=drvInfo; + // Show the error + nlwarning("3D: Vertex program syntax error line %d character %d\n", line, charC); - // Compile the program - nglLoadProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)program->getProgram().length(), (const GLubyte*)program->getProgram().c_str()); + // Setup not ok + delete drvInfo; + program->m_DrvInfo = NULL; + _GPUPrgDrvInfos.erase(it); + return false; + } - // Get loading error code - GLint errorOff; - glGetIntegerv (GL_PROGRAM_ERROR_POSITION_NV, &errorOff); + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; - // Compilation error ? - if (errorOff>=0) - { - // String length - uint length = (uint)program->getProgram ().length(); - const char* sString= program->getProgram ().c_str(); + // Build the feature info + program->buildInfo(source); - // Line count and char count - uint line=1; - uint charC=1; + // Setup ok + return true; - // Find the line - uint offset=0; - while ((offset((IProgramDrvInfos*)program->m_DrvInfo); + nlassert(drvInfo); - // Setup ok - return true; - } - else - { - // Cast the driver info pointer - drvInfo=safe_cast((IVertexProgramDrvInfos*)program->_DrvInfo); - } + // Enable vertex program + glEnable(GL_VERTEX_PROGRAM_NV); + _VertexProgramEnabled = true; // Setup this program - nglBindProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID); + nglBindProgramNV(GL_VERTEX_PROGRAM_NV, drvInfo->ID); _LastSetuppedVP = program; // Ok @@ -195,8 +225,8 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) else // Unsetup { // Disable vertex program - glDisable (GL_VERTEX_PROGRAM_NV); - _VertexProgramEnabled= false; + glDisable(GL_VERTEX_PROGRAM_NV); + _VertexProgramEnabled = false; // Ok return true; } @@ -1486,461 +1516,288 @@ bool CDriverGL::setupARBVertexProgram (const CVPParser::TProgram &inParsedProgra #endif } - - // *************************************************************************** -bool CDriverGL::activeARBVertexProgram (CVertexProgram *program) + +bool CDriverGL::compileARBVertexProgram(NL3D::CVertexProgram *program) { - H_AUTO_OGL(CDriverGL_activeARBVertexProgram); + H_AUTO_OGL(CDriverGL_compileARBVertexProgram); #ifndef USE_OPENGLES - // Setup or unsetup ? - if (program) - { - // Driver info - CVertexProgamDrvInfosGL *drvInfo; - // Program setuped ? - if (program->_DrvInfo==NULL) - { - // try to parse the program - CVPParser parser; - CVPParser::TProgram parsedProgram; - std::string errorOutput; - bool result = parser.parse(program->getProgram().c_str(), parsedProgram, errorOutput); - if (!result) - { - nlwarning("Unable to parse a vertex program."); - #ifdef NL_DEBUG - nlerror(errorOutput.c_str()); - #endif - return false; - } - // Insert into driver list. (so it is deleted when driver is deleted). - ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL); - - // Create a driver info - *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); - // Set the pointer - program->_DrvInfo=drvInfo; + nlassert(!program->m_DrvInfo); + glDisable(GL_VERTEX_PROGRAM_ARB); + _VertexProgramEnabled = false; - if (!setupARBVertexProgram(parsedProgram, drvInfo->ID, drvInfo->SpecularWritten)) - { - delete drvInfo; - program->_DrvInfo = NULL; - _VtxPrgDrvInfos.erase(it); - return false; - } - } - else - { - // Cast the driver info pointer - drvInfo=safe_cast((IVertexProgramDrvInfos*)program->_DrvInfo); - } - glEnable( GL_VERTEX_PROGRAM_ARB ); - _VertexProgramEnabled = true; - nglBindProgramARB( GL_VERTEX_PROGRAM_ARB, drvInfo->ID ); - if (drvInfo->SpecularWritten) - { - glEnable( GL_COLOR_SUM_ARB ); - } - else + // Find nelvp + IProgram::CSource *source = NULL; + for (uint i = 0; i < program->getSourceNb(); ++i) + { + if (program->getSource(i)->Profile == CVertexProgram::nelvp) { - glDisable( GL_COLOR_SUM_ARB ); // no specular written + source = program->getSource(i); } - _LastSetuppedVP = program; } - else + if (!source) { - glDisable( GL_VERTEX_PROGRAM_ARB ); - glDisable( GL_COLOR_SUM_ARB ); - _VertexProgramEnabled = false; + nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used"); + return false; + } + + // try to parse the program + 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."); + #ifdef NL_DEBUG + nlerror(errorOutput.c_str()); + #endif + return false; } + // Insert into driver list. (so it is deleted when driver is deleted). + ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IProgramDrvInfos*)NULL); + + // Create a driver info + CVertexProgamDrvInfosGL *drvInfo; + *it = drvInfo = new CVertexProgamDrvInfosGL(this, it); + // Set the pointer + program->m_DrvInfo = drvInfo; + + if (!setupARBVertexProgram(parsedProgram, drvInfo->ID, drvInfo->SpecularWritten)) + { + delete drvInfo; + program->m_DrvInfo = NULL; + _GPUPrgDrvInfos.erase(it); + return false; + } + + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; + + // Build the feature info + program->buildInfo(source); + return true; + #else + return false; + #endif } // *************************************************************************** -bool CDriverGL::activeEXTVertexShader (CVertexProgram *program) + +bool CDriverGL::activeARBVertexProgram(CVertexProgram *program) { - H_AUTO_OGL(CDriverGL_activeEXTVertexShader); + H_AUTO_OGL(CDriverGL_activeARBVertexProgram); #ifndef USE_OPENGLES + // Setup or unsetup ? if (program) { // Driver info - CVertexProgamDrvInfosGL *drvInfo; + CVertexProgamDrvInfosGL *drvInfo = safe_cast((IProgramDrvInfos*)program->m_DrvInfo); + nlassert(drvInfo); - // Program setuped ? - if (program->_DrvInfo==NULL) + glEnable( GL_VERTEX_PROGRAM_ARB ); + _VertexProgramEnabled = true; + nglBindProgramARB(GL_VERTEX_PROGRAM_ARB, drvInfo->ID); + if (drvInfo->SpecularWritten) { - // try to parse the program - CVPParser parser; - CVPParser::TProgram parsedProgram; - std::string errorOutput; - bool result = parser.parse(program->getProgram().c_str(), parsedProgram, errorOutput); - if (!result) - { - nlwarning("Unable to parse a vertex program."); - #ifdef NL_DEBUG - nlerror(errorOutput.c_str()); - #endif - return false; - } - - /* - FILE *f = fopen(getLogDirectory() + "test.txt", "wb"); - if (f) - { - std::string vpText; - CVPParser::dump(parsedProgram, vpText); - fwrite(vpText.c_str(), vpText.size(), 1, f); - fclose(f); - } - */ - - // Insert into driver list. (so it is deleted when driver is deleted). - ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL); - - // Create a driver info - *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); - // Set the pointer - program->_DrvInfo=drvInfo; - - if (!setupEXTVertexShader(parsedProgram, drvInfo->ID, drvInfo->Variants, drvInfo->UsedVertexComponents)) - { - delete drvInfo; - program->_DrvInfo = NULL; - _VtxPrgDrvInfos.erase(it); - return false; - } + glEnable(GL_COLOR_SUM_ARB); } else { - // Cast the driver info pointer - drvInfo=safe_cast((IVertexProgramDrvInfos*)program->_DrvInfo); + glDisable(GL_COLOR_SUM_ARB); // no specular written } - - glEnable( GL_VERTEX_SHADER_EXT); - _VertexProgramEnabled = true; - nglBindVertexShaderEXT( drvInfo->ID ); _LastSetuppedVP = program; } else { - glDisable( GL_VERTEX_SHADER_EXT ); + glDisable(GL_VERTEX_PROGRAM_ARB); + glDisable(GL_COLOR_SUM_ARB); _VertexProgramEnabled = false; } return true; -#else - return false; -#endif -} -// *************************************************************************** -bool CDriverGL::activeVertexProgram (CVertexProgram *program) -{ - H_AUTO_OGL(CDriverGL_activeVertexProgram) - // Extension here ? - if (_Extensions.NVVertexProgram) - { - return activeNVVertexProgram(program); - } - else if (_Extensions.ARBVertexProgram) - { - return activeARBVertexProgram(program); - } - else if (_Extensions.EXTVertexShader) - { - return activeEXTVertexShader(program); - } +#else - // Can't do anything return false; -} +#endif +} // *************************************************************************** -void CDriverGL::setConstant (uint index, float f0, float f1, float f2, float f3) +bool CDriverGL::compileEXTVertexShader(CVertexProgram *program) { - H_AUTO_OGL(CDriverGL_setConstant); + H_AUTO_OGL(CDriverGL_activeEXTVertexShader); #ifndef USE_OPENGLES - // Vertex program exist ? - if (_Extensions.NVVertexProgram) + + nlassert(program->m_DrvInfo); + glDisable(GL_VERTEX_SHADER_EXT); + _VertexProgramEnabled = false; + + // Find nelvp + IProgram::CSource *source = NULL; + for (uint i = 0; i < program->getSourceNb(); ++i) { - // Setup constant - nglProgramParameter4fNV (GL_VERTEX_PROGRAM_NV, index, f0, f1, f2, f3); + if (program->getSource(i)->Profile == CVertexProgram::nelvp) + { + source = program->getSource(i); + } } - else if (_Extensions.ARBVertexProgram) + if (!source) { - nglProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, index, f0, f1, f2, f3); + nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used"); + return false; } - else if (_Extensions.EXTVertexShader) + + // try to parse the program + CVPParser parser; + CVPParser::TProgram parsedProgram; + std::string errorOutput; + bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); + if (!result) { - float datas[] = { f0, f1, f2, f3 }; - nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, datas); + nlwarning("Unable to parse a vertex program."); + #ifdef NL_DEBUG + nlerror(errorOutput.c_str()); + #endif + return false; } -#endif -} + /* + FILE *f = fopen(getLogDirectory() + "test.txt", "wb"); + if (f) + { + std::string vpText; + CVPParser::dump(parsedProgram, vpText); + fwrite(vpText.c_str(), vpText.size(), 1, f); + fclose(f); + } + */ -// *************************************************************************** + // Insert into driver list. (so it is deleted when driver is deleted). + ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IProgramDrvInfos*)NULL); -void CDriverGL::setConstant (uint index, double d0, double d1, double d2, double d3) -{ - H_AUTO_OGL(CDriverGL_setConstant); + // Create a driver info + CVertexProgamDrvInfosGL *drvInfo; + *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); + // Set the pointer + program->m_DrvInfo=drvInfo; -#ifndef USE_OPENGLES - // Vertex program exist ? - if (_Extensions.NVVertexProgram) + if (!setupEXTVertexShader(parsedProgram, drvInfo->ID, drvInfo->Variants, drvInfo->UsedVertexComponents)) { - // Setup constant - nglProgramParameter4dNV (GL_VERTEX_PROGRAM_NV, index, d0, d1, d2, d3); - } - else if (_Extensions.ARBVertexProgram) - { - nglProgramEnvParameter4dARB(GL_VERTEX_PROGRAM_ARB, index, d0, d1, d2, d3); - } - else if (_Extensions.EXTVertexShader) - { - double datas[] = { d0, d1, d2, d3 }; - nglSetInvariantEXT(_EVSConstantHandle + index, GL_DOUBLE, datas); + delete drvInfo; + program->m_DrvInfo = NULL; + _GPUPrgDrvInfos.erase(it); + return false; } -#endif -} + // Set parameters for assembly programs + drvInfo->ParamIndices = source->ParamIndices; -// *************************************************************************** + // Build the feature info + program->buildInfo(source); -void CDriverGL::setConstant (uint index, const NLMISC::CVector& value) -{ - H_AUTO_OGL(CDriverGL_setConstant); + return true; + +#else + + return false; -#ifndef USE_OPENGLES - // Vertex program exist ? - if (_Extensions.NVVertexProgram) - { - // Setup constant - nglProgramParameter4fNV (GL_VERTEX_PROGRAM_NV, index, value.x, value.y, value.z, 0); - } - else if (_Extensions.ARBVertexProgram) - { - nglProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, index, value.x, value.y, value.z, 0); - } - else if (_Extensions.EXTVertexShader) - { - float datas[] = { value.x, value.y, value.z, 0 }; - nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, datas); - } #endif } - // *************************************************************************** -void CDriverGL::setConstant (uint index, const NLMISC::CVectorD& value) +bool CDriverGL::activeEXTVertexShader(CVertexProgram *program) { - H_AUTO_OGL(CDriverGL_setConstant); + H_AUTO_OGL(CDriverGL_activeEXTVertexShader); #ifndef USE_OPENGLES - // Vertex program exist ? - if (_Extensions.NVVertexProgram) - { - // Setup constant - nglProgramParameter4dNV (GL_VERTEX_PROGRAM_NV, index, value.x, value.y, value.z, 0); - } - else if (_Extensions.ARBVertexProgram) + + // Setup or unsetup ? + if (program) { - nglProgramEnvParameter4dARB(GL_VERTEX_PROGRAM_ARB, index, value.x, value.y, value.z, 0); + // Driver info + CVertexProgamDrvInfosGL *drvInfo = safe_cast((IProgramDrvInfos*)program->m_DrvInfo); + nlassert(drvInfo); + + glEnable(GL_VERTEX_SHADER_EXT); + _VertexProgramEnabled = true; + nglBindVertexShaderEXT(drvInfo->ID); + _LastSetuppedVP = program; } - else if (_Extensions.EXTVertexShader) + else { - double datas[] = { value.x, value.y, value.z, 0 }; - nglSetInvariantEXT(_EVSConstantHandle + index, GL_DOUBLE, datas); + glDisable(GL_VERTEX_SHADER_EXT); + _VertexProgramEnabled = false; } -#endif -} + return true; +#else -// *************************************************************************** -void CDriverGL::setConstant (uint index, uint num, const float *src) -{ - H_AUTO_OGL(CDriverGL_setConstant); + return false; -#ifndef USE_OPENGLES - // Vertex program exist ? - if (_Extensions.NVVertexProgram) - { - nglProgramParameters4fvNV(GL_VERTEX_PROGRAM_NV, index, num, src); - } - else if (_Extensions.ARBVertexProgram) - { - for(uint k = 0; k < num; ++k) - { - nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + k, src + 4 * k); - } - } - else if (_Extensions.EXTVertexShader) - { - for(uint k = 0; k < num; ++k) - { - nglSetInvariantEXT(_EVSConstantHandle + index + k, GL_FLOAT, (void *) (src + 4 * k)); - } - } #endif } -// *************************************************************************** -void CDriverGL::setConstant (uint index, uint num, const double *src) +bool CDriverGL::compileVertexProgram(NL3D::CVertexProgram *program) { - H_AUTO_OGL(CDriverGL_setConstant); - -#ifndef USE_OPENGLES - // Vertex program exist ? - if (_Extensions.NVVertexProgram) - { - nglProgramParameters4dvNV(GL_VERTEX_PROGRAM_NV, index, num, src); - } - else if (_Extensions.ARBVertexProgram) + if (program->m_DrvInfo == NULL) { - for(uint k = 0; k < num; ++k) + // Extension + if (_Extensions.NVVertexProgram) { - nglProgramEnvParameter4dvARB(GL_VERTEX_PROGRAM_ARB, index + k, src + 4 * k); + return compileNVVertexProgram(program); } - } - else if (_Extensions.EXTVertexShader) - { - for(uint k = 0; k < num; ++k) + else if (_Extensions.ARBVertexProgram) + { + return compileARBVertexProgram(program); + } + else if (_Extensions.EXTVertexShader) { - nglSetInvariantEXT(_EVSConstantHandle + index + k, GL_DOUBLE, (void *) (src + 4 * k)); + return compileEXTVertexShader(program); } + + // Can't do anything + return false; } -#endif + return true; } // *************************************************************************** -const uint CDriverGL::GLMatrix[IDriver::NumMatrix]= +bool CDriverGL::activeVertexProgram(CVertexProgram *program) { - GL_MODELVIEW, - GL_PROJECTION, -#ifdef USE_OPENGLES - GL_MODELVIEW -#else - GL_MODELVIEW_PROJECTION_NV -#endif -}; - - -// *************************************************************************** - -const uint CDriverGL::GLTransform[IDriver::NumTransform]= -{ -#ifdef USE_OPENGLES - 0, - 0, - 0, - 0 -#else - GL_IDENTITY_NV, - GL_INVERSE_NV, - GL_TRANSPOSE_NV, - GL_INVERSE_TRANSPOSE_NV -#endif -}; - - -// *************************************************************************** + H_AUTO_OGL(CDriverGL_activeVertexProgram) -void CDriverGL::setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform) -{ - H_AUTO_OGL(CDriverGL_setConstantMatrix); + // Compile if necessary + if (program && !CDriverGL::compileVertexProgram(program)) return false; -#ifndef USE_OPENGLES - // Vertex program exist ? + // Extension if (_Extensions.NVVertexProgram) { - // First, ensure that the render setup is correclty setuped. - refreshRenderSetup(); - - // Track the matrix - nglTrackMatrixNV (GL_VERTEX_PROGRAM_NV, index, GLMatrix[matrix], GLTransform[transform]); - // Release Track => matrix data is copied. - nglTrackMatrixNV (GL_VERTEX_PROGRAM_NV, index, GL_NONE, GL_IDENTITY_NV); + return activeNVVertexProgram(program); } - else + else if (_Extensions.ARBVertexProgram) { - // First, ensure that the render setup is correctly setuped. - refreshRenderSetup(); - CMatrix mat; - switch (matrix) - { - case IDriver::ModelView: - mat = _ModelViewMatrix; - break; - case IDriver::Projection: - { - refreshProjMatrixFromGL(); - mat = _GLProjMat; - } - break; - case IDriver::ModelViewProjection: - refreshProjMatrixFromGL(); - mat = _GLProjMat * _ModelViewMatrix; - break; - default: - break; - } - - switch(transform) - { - case IDriver::Identity: break; - case IDriver::Inverse: - mat.invert(); - break; - case IDriver::Transpose: - mat.transpose(); - break; - case IDriver::InverseTranspose: - mat.invert(); - mat.transpose(); - break; - default: - break; - } - mat.transpose(); - float matDatas[16]; - mat.get(matDatas); - if (_Extensions.ARBVertexProgram) - { - nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index, matDatas); - nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + 1, matDatas + 4); - nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + 2, matDatas + 8); - nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + 3, matDatas + 12); - } - else - { - nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, matDatas); - nglSetInvariantEXT(_EVSConstantHandle + index + 1, GL_FLOAT, matDatas + 4); - nglSetInvariantEXT(_EVSConstantHandle + index + 2, GL_FLOAT, matDatas + 8); - nglSetInvariantEXT(_EVSConstantHandle + index + 3, GL_FLOAT, matDatas + 12); - } + return activeARBVertexProgram(program); + } + else if (_Extensions.EXTVertexShader) + { + return activeEXTVertexShader(program); } -#endif -} - -// *************************************************************************** -void CDriverGL::setConstantFog (uint index) -{ - H_AUTO_OGL(CDriverGL_setConstantFog) - const float *values = _ModelViewMatrix.get(); - setConstant (index, -values[2], -values[6], -values[10], -values[14]); + // Can't do anything + return false; } // *************************************************************************** diff --git a/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp b/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp index 475b58d57..3c0cf1c94 100644 --- a/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp +++ b/code/nel/src/3d/driver/opengl/unix_event_emitter.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "nel/misc/debug.h" @@ -566,7 +567,7 @@ bool CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server) } else { - k = XKeycodeToKeysym(_dpy, keyCode, 0); + k = XkbKeycodeToKeysym(_dpy, keyCode, 0, 0); } // send CEventKeyDown event only if keyCode is defined diff --git a/code/nel/src/3d/driver/opengl3/driver_glsl_program.cpp b/code/nel/src/3d/driver/opengl3/driver_glsl_program.cpp deleted file mode 100644 index f8331b618..000000000 --- a/code/nel/src/3d/driver/opengl3/driver_glsl_program.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// NeL - MMORPG Framework -// 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 . - - -#include "driver_glsl_program.h" -#include -#include "driver_opengl_extension.h" - -namespace NL3D -{ - CGLSLProgram::CGLSLProgram() : - IProgram() - { - std::fill( uniformIndices, uniformIndices + NUM_UNIFORMS, -1 ); - programId = 0; - } - - CGLSLProgram::~CGLSLProgram() - { - } - - void CGLSLProgram::cacheUniforms() - { - nlassert( programId != 0 ); - - for( int i = 0; i < NUM_UNIFORMS; i++ ) - { - uniformIndices[ i ] = nglGetUniformLocation( programId, uniformNames[ i ] ); - } - } - -} - - diff --git a/code/nel/src/3d/driver/opengl3/driver_glsl_program.h b/code/nel/src/3d/driver/opengl3/driver_glsl_program.h deleted file mode 100644 index bb4ccad6b..000000000 --- a/code/nel/src/3d/driver/opengl3/driver_glsl_program.h +++ /dev/null @@ -1,46 +0,0 @@ -// NeL - MMORPG Framework -// 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 . - - -#ifndef GLSL_PROGRAM_H -#define GLSL_PROGRAM_H - -#include "nel/3d/i_program.h" - -namespace NL3D -{ - /// Wrapper class for OpenGL shader program object - class CGLSLProgram : public IProgram - { - public: - CGLSLProgram(); - ~CGLSLProgram(); - - unsigned int getProgramId() const{ return programId; } - void setProgramId( unsigned int Id ){ programId = Id; } - - void cacheUniforms(); - int getUniformIndex( uint32 id ) const{ return uniformIndices[ id ]; } - - protected: - unsigned int programId; - int uniformIndices[ NUM_UNIFORMS ]; - }; - -} - -#endif - diff --git a/code/nel/src/3d/driver/opengl3/driver_glsl_shader_base.cpp b/code/nel/src/3d/driver/opengl3/driver_glsl_shader_base.cpp deleted file mode 100644 index 1c4088a24..000000000 --- a/code/nel/src/3d/driver/opengl3/driver_glsl_shader_base.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// NeL - MMORPG Framework -// 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 . - - -#include "driver_glsl_shader_base.h" -#include "stdopengl.h" -#include "driver_opengl_extension.h" - -#define MAX_SHADER_COMPILE_INFOLOG 1024 - - -namespace NL3D -{ - - void CGLSLShaderBase::shaderSource( const char *source ) - { - nlassert( shaderId != 0 ); - - const GLchar *p[1]; - p[ 0 ] = source; - GLint lengths[ 1 ]; - lengths[ 0 ] = strlen( source ); - - nglShaderSource( shaderId, 1, p, lengths ); - } - - bool CGLSLShaderBase::compile( std::string &log ) - { - nglCompileShader( shaderId ); - - GLint ok; - nglGetShaderiv( shaderId, GL_COMPILE_STATUS, &ok ); - - if( ok != GL_TRUE ) - { - char infoLog[ MAX_SHADER_COMPILE_INFOLOG ]; - nglGetShaderInfoLog( shaderId, MAX_SHADER_COMPILE_INFOLOG, NULL, infoLog ); - log.assign( infoLog ); - return false; - } - - compiled = true; - - return true; - } - -} - - - - diff --git a/code/nel/src/3d/driver/opengl3/driver_glsl_shader_generator.cpp b/code/nel/src/3d/driver/opengl3/driver_glsl_shader_generator.cpp index ec50bece0..09f4049a3 100644 --- a/code/nel/src/3d/driver/opengl3/driver_glsl_shader_generator.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_glsl_shader_generator.cpp @@ -155,7 +155,7 @@ namespace NL3D ss << "vec4 gl_Position;" << std::endl; ss << "};" << std::endl; ss << std::endl; - ss << "uniform mat4 mvpMatrix;" << std::endl; + ss << "uniform mat4 modelViewProjection;" << std::endl; ss << std::endl; for( int i = Position; i < NumOffsets; i++ ) @@ -292,9 +292,9 @@ namespace NL3D ss << "// Calculates the normal matrix from the modelview matrix" << std::endl; ss << "void calcNMFromMV()" << std::endl; ss << "{" << std::endl; - ss << "normalMatrix[ 0 ] = mvMatrix[ 0 ].xyz;" << std::endl; - ss << "normalMatrix[ 1 ] = mvMatrix[ 1 ].xyz;" << std::endl; - ss << "normalMatrix[ 2 ] = mvMatrix[ 2 ].xyz;" << std::endl; + ss << "normalMatrix[ 0 ] = modelView[ 0 ].xyz;" << std::endl; + ss << "normalMatrix[ 1 ] = modelView[ 1 ].xyz;" << std::endl; + ss << "normalMatrix[ 2 ] = modelView[ 2 ].xyz;" << std::endl; ss << "normalMatrix = inverse( normalMatrix );" << std::endl; ss << "normalMatrix = transpose( normalMatrix );" << std::endl; ss << "}" << std::endl; @@ -368,7 +368,7 @@ namespace NL3D break; case CShaderDesc::Directional: - ss << "uniform vec3 light" << i << "Dir;" << std::endl; + ss << "uniform vec3 light" << i << "DirOrPos;" << std::endl; ss << "uniform vec4 light" << i << "ColDiff;" << std::endl; ss << "uniform vec4 light" << i << "ColAmb;" << std::endl; ss << "uniform vec4 light" << i << "ColSpec;" << std::endl; @@ -376,7 +376,7 @@ namespace NL3D break; case CShaderDesc::Point: - ss << "uniform vec3 light" << i << "Pos;" << std::endl; + ss << "uniform vec3 light" << i << "DirOrPos;" << std::endl; ss << "uniform vec4 light" << i << "ColDiff;" << std::endl; ss << "uniform vec4 light" << i << "ColAmb;" << std::endl; ss << "uniform vec4 light" << i << "ColSpec;" << std::endl; @@ -438,7 +438,7 @@ namespace NL3D ss << "vec4 getLight" << num << "Color()" << std::endl; ss << "{" << std::endl; - ss << "vec4 lightDir4 = mvMatrix * vec4( light" << num << "Dir, 1.0 );" << std::endl; + ss << "vec4 lightDir4 = modelView * vec4( light" << num << "DirOrPos, 1.0 );" << std::endl; ss << "vec3 lightDir = lightDir4.xyz / lightDir4.w;" << std::endl; ss << "vec3 normal3 = vnormal.xyz / vnormal.w;" << std::endl; ss << "normal3 = normalMatrix * normal3;" << std::endl; @@ -473,7 +473,7 @@ namespace NL3D ss << "vec4 getLight" << num << "Color()" << std::endl; ss << "{" << std::endl; ss << "vec3 ecPos3 = ecPos4.xyz / ecPos4.w;" << std::endl; - ss << "vec4 lightPos4 = mvMatrix * vec4( light" << num << "Pos, 1.0 );" << std::endl; + ss << "vec4 lightPos4 = modelView * vec4( light" << num << "DirOrPos, 1.0 );" << std::endl; ss << "vec3 lightPos = lightPos4.xyz / lightPos4.w;" << std::endl; ss << "vec3 lightDirection = lightPos - ecPos3;" << std::endl; ss << "float lightDistance = length( lightDirection );" << std::endl; @@ -551,7 +551,7 @@ namespace NL3D { if( desc->fogEnabled() || desc->lightingEnabled() ) { - ss << "uniform mat4 mvMatrix;" << std::endl; + ss << "uniform mat4 modelView;" << std::endl; } if( desc->fogEnabled() || desc->hasPointLight() ) { @@ -582,10 +582,10 @@ namespace NL3D if( desc->lightingEnabled() ) ss << "calcNMFromMV();" << std::endl; - ss << "gl_Position = mvpMatrix * " << "v" << attribNames[ 0 ] << ";" << std::endl; + ss << "gl_Position = modelViewProjection * " << "v" << attribNames[ 0 ] << ";" << std::endl; if( desc->fogEnabled() || desc->hasPointLight() ) - ss << "ecPos4 = mvMatrix * v" << attribNames[ 0 ] << ";" << std::endl; + ss << "ecPos4 = modelView * v" << attribNames[ 0 ] << ";" << std::endl; if( desc->fogEnabled() ) ss << "ecPos = ecPos4;" << std::endl; @@ -609,7 +609,7 @@ namespace NL3D void CGLSLShaderGenerator::generateSpecularVS() { - ss << "uniform mat4 mvMatrix;" << std::endl; + ss << "uniform mat4 modelView;" << std::endl; ss << "uniform mat4 texMatrix0;" << std::endl; ss << "smooth out vec3 cubeTexCoords;" << std::endl; @@ -644,7 +644,7 @@ namespace NL3D ss << "void main( void )" << std::endl; ss << "{" << std::endl; - ss << "vec4 eyePosition = mvMatrix * v" << attribNames[ 0 ] << ";" << std::endl; + ss << "vec4 eyePosition = modelView * v" << attribNames[ 0 ] << ";" << std::endl; if( desc->lightingEnabled() ) ss << "calcNMFromMV();" << std::endl; @@ -661,7 +661,7 @@ namespace NL3D ss << "vec4 t = vec4( cubeTexCoords, 1.0 );" << std::endl; ss << "t = t * texMatrix0;" << std::endl; ss << "cubeTexCoords = t.xyz;" << std::endl; - ss << "gl_Position = mvpMatrix * v" << attribNames[ 0 ] << ";" << std::endl; + ss << "gl_Position = modelViewProjection * v" << attribNames[ 0 ] << ";" << std::endl; if( desc->lightingEnabled() ) addLightsVS(); @@ -698,7 +698,7 @@ namespace NL3D ss << "void main( void )" << std::endl; ss << "{" << std::endl; - ss << "gl_Position = mvpMatrix * v" << attribNames[ 0 ] << ";" << std::endl; + ss << "gl_Position = modelViewProjection * v" << attribNames[ 0 ] << ";" << std::endl; for( int i = Weight; i < NumOffsets; i++ ) { @@ -767,18 +767,18 @@ namespace NL3D ss << "uniform vec4 bumpMap1Offset;" << std::endl; // no fog yet - //ss << "uniform mat4 mvMatrix;" << std::endl; + //ss << "uniform mat4 modelView;" << std::endl; ss << std::endl; ss << "void main( void )" << std::endl; ss << "{" << std::endl; ss << "position = vposition;" << std::endl; - ss << "gl_Position = mvpMatrix * position;" << std::endl; + ss << "gl_Position = modelViewProjection * position;" << std::endl; ss << "bump0ScaleBias = bumpMap0Scale;" << std::endl; ss << "bump1ScaleBias = bumpMap1Scale;" << std::endl; // no fog yet - //ss << "vec4 v = mvMatrix[ 3 ];" << std::endl; + //ss << "vec4 v = modelView[ 3 ];" << std::endl; //fog.x = dot( position, v ); ss << "texCoord0 = position * bumpMap0Scale + bumpMap0Offset;" << std::endl; diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl.cpp index a9f7a578d..552f2bcb2 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl.cpp @@ -320,11 +320,11 @@ CDriverGL3::CDriverGL3() _TextureTargetCubeFace = 0; _TextureTargetUpload = false; - vertexProgram = NULL; - pixelProgram = NULL; - - dynMatVP = NULL; - dynMatPP = NULL; + currentProgram.vp = NULL; + currentProgram.pp = NULL; + currentProgram.gp = NULL; + currentProgram.dynmatVP = NULL; + currentProgram.dynmatPP = NULL; shaderGenerator = new CGLSLShaderGenerator(); usrShaderManager = new CUsrShaderManager(); @@ -341,16 +341,17 @@ CDriverGL3::~CDriverGL3() release(); - vertexProgram = NULL; - pixelProgram = NULL; - - if( dynMatVP != NULL ) - delete dynMatVP; - dynMatVP = NULL; + currentProgram.vp = NULL; + currentProgram.pp = NULL; + currentProgram.gp = NULL; + + if( currentProgram.dynmatVP != NULL ) + delete currentProgram.dynmatVP; + currentProgram.dynmatVP = NULL; - if( dynMatPP != NULL ) - delete dynMatPP; - dynMatPP = NULL; + if( currentProgram.dynmatPP != NULL ) + delete currentProgram.dynmatPP; + currentProgram.dynmatPP = NULL; delete shaderGenerator; shaderGenerator = NULL; @@ -1184,17 +1185,6 @@ uint32 CDriverGL3::getUsedTextureMemory() const } -// *************************************************************************** -bool CDriverGL3::isWaterShaderSupported() const -{ - H_AUTO_OGL(CDriverGL3_isWaterShaderSupported); - - if(ARBWaterShader[0] != 0) return true; - - if ( !_Extensions.ATIFragmentShader ) return false; - return true; -} - // *************************************************************************** void CDriverGL3::setMatrix2DForTextureOffsetAddrMode(const uint stage, const float mat[4]) { @@ -2135,14 +2125,6 @@ CVertexBuffer::TVertexColorType CDriverGL3::getVertexColorFormat() const return CVertexBuffer::TRGBA; } -// *************************************************************************** -bool CDriverGL3::activeShader(CShader * /* shd */) -{ - H_AUTO_OGL(CDriverGL3_activeShader) - - return false; -} - // *************************************************************************** void CDriverGL3::startBench (bool wantStandardDeviation, bool quick, bool reset) { @@ -2494,6 +2476,47 @@ void CDriverGL3::reloadUserShaders() loader.loadShaders( "./shaders" ); } +CVertexProgramDrvInfosGL3::CVertexProgramDrvInfosGL3( CDriverGL3 *drv, ItGPUPrgDrvInfoPtrList it ) : +IProgramDrvInfos( drv, it ) +{ + programId = 0; +} + +CVertexProgramDrvInfosGL3::~CVertexProgramDrvInfosGL3() +{ + programId = 0; +} + +uint CVertexProgramDrvInfosGL3::getUniformIndex( const char *name ) const +{ + int idx = nglGetUniformLocation( programId, name ); + if( idx == -1 ) + return ~0; + else + return idx; +} + +CPixelProgramDrvInfosGL3::CPixelProgramDrvInfosGL3( CDriverGL3 *drv, ItGPUPrgDrvInfoPtrList it ) : +IProgramDrvInfos( drv, it ) +{ + programId = 0; +} + +CPixelProgramDrvInfosGL3::~CPixelProgramDrvInfosGL3() +{ + programId = 0; +} + +uint CPixelProgramDrvInfosGL3::getUniformIndex( const char *name ) const +{ + int idx = nglGetUniformLocation( programId, name ); + if( idx == -1 ) + return ~0; + else + return idx; +} + + // *************************************************************************** void displayGLError(GLenum error) { diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl.h b/code/nel/src/3d/driver/opengl3/driver_opengl.h index 799c0a738..60679428d 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl3/driver_opengl.h @@ -49,7 +49,6 @@ #include "nel/3d/driver.h" #include "nel/3d/material.h" -#include "nel/3d/shader.h" #include "nel/3d/vertex_buffer.h" #include "nel/3d/ptr_set.h" #include "nel/3d/texture_cube.h" @@ -204,7 +203,7 @@ public: // Verex buffer hard ? IVertexBufferHardGL *_VBHard; - class CDriverGL3 *_DriverGL; + CDriverGL3 *_DriverGL; // From IVBDrvInfos virtual ~CVBDrvInfosGL3(); @@ -280,9 +279,25 @@ public: class CGLSLShaderGenerator; class CUsrShaderManager; -class CGLSLProgram; -class CGLSLVertexProgram; -class CGLSLPixelProgram; +struct SProgram +{ + CVertexProgram *vp; + CPixelProgram *pp; + CGeometryProgram *gp; + + CVertexProgram *dynmatVP; + CPixelProgram *dynmatPP; + + SProgram() + { + vp = NULL; + pp = NULL; + gp = NULL; + dynmatVP = NULL; + dynmatPP = NULL; + } +}; + // *************************************************************************** class CDriverGL3 : public IDriver @@ -300,9 +315,10 @@ public: virtual bool init (uint windowIcon = 0, emptyProc exitFunc = 0); virtual void disableHardwareVertexProgram(){} + virtual void disableHardwarePixelProgram(){} virtual void disableHardwareVertexArrayAGP(){} - virtual void disableHardwareTextureShader(){}; - + virtual void disableHardwareTextureShader(){} + virtual bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable) throw(EBadDisplay); virtual bool setMode(const GfxMode& mode); virtual bool getModes(std::vector &modes); @@ -384,7 +400,7 @@ public: bool setupProgram(CMaterial& mat); bool setupDynMatProgram(CMaterial& mat, uint pass); void setupUniforms(); - void setupUniforms( CGLSLProgram *program ); + void setupUniforms( TProgram program ); virtual void startSpecularBatch(); virtual void endSpecularBatch(); @@ -402,8 +418,6 @@ public: virtual CMatrix getViewMatrix() const; - virtual bool activeShader(CShader *shd); - virtual void forceNormalize(bool normalize) { _ForceNormalize= normalize; @@ -561,6 +575,7 @@ public: virtual bool setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width, uint32 height, uint32 mipmapLevel, uint32 cubeFace); + virtual ITexture* getRenderTarget() const{ return _TextureTarget; } virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y, uint32 width, uint32 height, uint32 mipmapLevel); @@ -599,9 +614,9 @@ public: // @{ virtual bool supportTextureShaders() const{ return false; }; - virtual bool isWaterShaderSupported() const; + virtual bool supportWaterShader() const{ return true; } - virtual bool isTextureAddrModeSupported(CMaterial::TTexAddressingMode mode) const{ return false; }; + virtual bool supportTextureAddrMode(CMaterial::TTexAddressingMode mode) const{ return false; }; virtual void setMatrix2DForTextureOffsetAddrMode(const uint stage, const float mat[4]); // @} @@ -1219,43 +1234,59 @@ private: // @} - /// \name Vertex program interface - // @{ + public: + + bool isVertexProgramSupported() const{ return true; } + + bool isVertexProgramEmulated() const{ return false; } + + bool supportVertexProgram(CVertexProgram::TProfile profile) const; + + bool compileVertexProgram(CVertexProgram *program); + + bool activeVertexProgram(CVertexProgram *program); + + bool supportPixelProgram(CPixelProgram::TProfile profile) const; + + bool compilePixelProgram(CPixelProgram *program); + + bool activePixelProgram(CPixelProgram *program); + + bool supportGeometryProgram(CGeometryProgram::TProfile profile) const{ return false; } + + bool compileGeometryProgram(CGeometryProgram *program){ return false; } - bool isVertexProgramSupported () const{ return true; } - bool isVertexProgramEmulated () const{ return false; } - bool activeVertexProgram (CVertexProgram *program){ return true; }; - - bool compileVertexProgram( CGLSLVertexProgram *program ); - bool activeVertexProgram( CGLSLVertexProgram *program ); - - bool compilePixelProgram( CGLSLPixelProgram *program ); - bool activePixelProgram( CGLSLPixelProgram *program ); - - IProgram* createVertexProgram() const; - IProgram* createPixelProgram() const; - - int getUniformLocation( uint32 programType, const char *name ); - - void setUniform1f( uint32 programType, uint index, float f ); - void setUniform3f( uint32 programType, uint index, float f1, float f2, float f3 ); - void setUniform4f( uint32 programType, uint index, float f1, float f2, float f3, float f4 ); - void setUniform1i( uint32 programType, uint index, int i ); - void setUniform4i( uint32 programType, uint index, int i1, int i2, int i3, int i4 ); - void setUniform1u( uint32 programType, uint index, uint u ); - void setUniform4u( uint32 programType, uint index, uint u1, uint u2, uint u3, uint u4 ); - void setUniformMatrix2fv( uint32 programType, uint index, uint count, bool transpose, const float *values ); - void setUniformMatrix3fv( uint32 programType, uint index, uint count, bool transpose, const float *values ); - void setUniformMatrix4fv( uint32 programType, uint index, uint count, bool transpose, const float *values ); - - void setConstant (uint index, float, float, float, float){} - void setConstant (uint index, double, double, double, double){} - void setConstant (uint indexStart, const NLMISC::CVector& value){} - void setConstant (uint indexStart, const NLMISC::CVectorD& value){} - void setConstant (uint index, uint num, const float *src){} - void setConstant (uint index, uint num, const double *src){} - void setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform){} - void setConstantFog (uint index){} + bool activeGeometryProgram(CGeometryProgram *program){ return false; } + + uint32 getProgramId( TProgram program ) const; + IProgram* getProgram( TProgram program ) const; + + int getUniformLocation( TProgram program, const char *name ); + void setUniform1f(TProgram program, uint index, float f0); + void setUniform2f(TProgram program, uint index, float f0, float f1); + void setUniform3f(TProgram program, uint index, float f0, float f1, float f2); + void setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3); + void setUniform1i(TProgram program, uint index, sint32 i0); + void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1); + void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2); + void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3); + void setUniform1ui(TProgram program, uint index, uint32 ui0); + void setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1); + void setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2); + void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3); + void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v); + void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3); + void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba); + void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m); + void setUniform4x4f(TProgram program, uint index, const float *src ); + void setUniform4fv(TProgram program, uint index, size_t num, const float *src); + void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src); + void setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src); + + void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform); + void setUniformFog(TProgram program, uint index); + + bool isUniformProgramState(){ return false; } void enableVertexProgramDoubleSidedColor(bool doubleSided){} bool supportVertexProgramDoubleSidedColor() const{ return true; }; @@ -1274,6 +1305,8 @@ private: return true; } + private: + // The last vertex program that was setupped NLMISC::CRefPtr _LastSetuppedVP; @@ -1316,11 +1349,7 @@ private: bool initPipeline(); uint32 ppoId; - CGLSLVertexProgram *vertexProgram; - CGLSLPixelProgram *pixelProgram; - - CGLSLVertexProgram *dynMatVP; - CGLSLPixelProgram *dynMatPP; + SProgram currentProgram; // init EMBM settings (set each stage to modify the next) void initEMBM(); @@ -1414,6 +1443,34 @@ public: }; + +class CVertexProgramDrvInfosGL3 : public IProgramDrvInfos +{ +public: + CVertexProgramDrvInfosGL3( CDriverGL3 *drv, ItGPUPrgDrvInfoPtrList it ); + ~CVertexProgramDrvInfosGL3(); + uint getUniformIndex( const char *name ) const; + uint getProgramId() const{ return programId; } + void setProgramId( uint id ){ programId = id; } + +private: + uint programId; +}; + +class CPixelProgramDrvInfosGL3 : public IProgramDrvInfos +{ +public: + CPixelProgramDrvInfosGL3( CDriverGL3 *drv, ItGPUPrgDrvInfoPtrList it ); + ~CPixelProgramDrvInfosGL3(); + uint getUniformIndex( const char *name ) const; + uint getProgramId() const{ return programId; } + void setProgramId( uint id ){ programId = id; } + +private: + uint programId; + +}; + #ifdef NL_STATIC } // NLDRIVERGL/ES #endif diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_material.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_material.cpp index fade202c4..b4a72d9d1 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_material.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_material.cpp @@ -21,8 +21,6 @@ #include "nel/3d/texture_bump.h" #include "nel/3d/material.h" #include "nel/3d/dynamic_material.h" -#include "driver_glsl_vertex_program.h" -#include "driver_glsl_pixel_program.h" namespace NL3D { @@ -602,39 +600,41 @@ bool CDriverGL3::setupDynMatPass( uint pass ) _DriverGLStates.enableCullFace( true ); CDynMaterial *m = _CurrentMaterial->getDynMat(); - SRenderPass *p = m->getPass( pass ); + SRenderPass *currentPass = m->getPass( pass ); - CGLSLProgram *currentProgram; - uint32 type; + IProgram *p; - CGLSLProgram* programs[ 2 ]; - programs[ 0 ] = vertexProgram; - programs[ 1 ] = pixelProgram; + IProgram* programs[ 2 ]; + programs[ 0 ] = currentProgram.vp; + programs[ 1 ] = currentProgram.pp; + + IDriver::TProgram type[ 2 ]; + type[ 0 ] = IDriver::VertexProgram; + type[ 1 ] = IDriver::PixelProgram; for( uint32 j = 0; j < 2; j++ ) { - currentProgram = programs[ j ]; - type = currentProgram->getType(); + p = programs[ j ]; - for( uint32 i = 0; i < p->count(); i++ ) + for( uint32 i = 0; i < currentPass->count(); i++ ) { - const SDynMaterialProp *prop = p->getProperty( i ); - int loc = nglGetUniformLocation( currentProgram->getProgramId(), prop->prop.c_str() ); + const SDynMaterialProp *prop = currentPass->getProperty( i ); + int loc = getUniformLocation( type[ j ], prop->prop.c_str() ); if( loc == -1 ) continue; switch( prop->type ) { case SDynMaterialProp::Float: - setUniform1f( type, loc, prop->value.toFloat() ); + setUniform1f( type[ j ], loc, prop->value.toFloat() ); break; case SDynMaterialProp::Int: - setUniform1i( type, loc, prop->value.toInt() ); + setUniform1i( type[ j ], loc, prop->value.toInt() ); break; case SDynMaterialProp::Uint: - setUniform1u( type, loc, prop->value.toUInt() ); + setUniform1ui( type[ j ], loc, prop->value.toUInt() ); break; case SDynMaterialProp::Color: @@ -642,10 +642,10 @@ bool CDriverGL3::setupDynMatPass( uint pass ) float v[ 4 ]; prop->value.getVector4( v ); - for( int j = 0; j < 4; j++ ) - v[ j ] = v[ j ] / 255.0f; + for( int k = 0; k < 4; k++ ) + v[ k ] = v[ k ] / 255.0f; - setUniform4f( type, loc, v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] ); + setUniform4f( type[ j ], loc, v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] ); } break; @@ -653,7 +653,7 @@ bool CDriverGL3::setupDynMatPass( uint pass ) { float v[ 4 ]; prop->value.getVector4( v ); - setUniform4f( type, loc, v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] ); + setUniform4f( type[ j ], loc, v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] ); } break; @@ -661,7 +661,7 @@ bool CDriverGL3::setupDynMatPass( uint pass ) { float m[ 16 ]; prop->value.getMatrix4( m ); - setUniformMatrix4fv( type, loc, 1, false, m ); + setUniform4x4f( type[ j ], loc, m ); break; } @@ -673,17 +673,17 @@ bool CDriverGL3::setupDynMatPass( uint pass ) ////////////////////////////////// Set up some standard uniforms ////////////////////////////////// int loc = -1; - loc = nglGetUniformLocation( currentProgram->getProgramId(), "mvpMatrix" ); + loc = getUniformLocation( type[ j ], "mvpMatrix" ); if( loc != -1 ) { CMatrix mat = _GLProjMat * _ModelViewMatrix; - setUniformMatrix4fv( type, loc, 1, false, mat.get() ); + setUniform4x4f( type[ j ], loc, mat ); } - loc = nglGetUniformLocation( currentProgram->getProgramId(), "mvMatrix" ); + loc = getUniformLocation( type[ j ], "mvMatrix" ); if( loc != -1 ) { - setUniformMatrix4fv( type, loc, 1, false, _ModelViewMatrix.get() ); + setUniform4x4f( type[ j ], loc, _ModelViewMatrix ); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -700,12 +700,12 @@ void CDriverGL3::setupNormalPass() for( int i = 0; i < IDRV_MAT_MAXTEXTURES; i++ ) { // Set constant - int cl = pixelProgram->getUniformIndex( IProgram::EUniform( IProgram::Constant0 + i ) ); + int cl = currentProgram.pp->getUniformIndex( CProgramIndex::TName( CProgramIndex::Constant0 + i ) ); if( cl != -1 ) { GLfloat glCol[ 4 ]; convColor( mat._TexEnvs[ i ].ConstantColor, glCol ); - setUniform4f( IProgram::PIXEL_PROGRAM, cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); + setUniform4f( IDriver::PixelProgram, cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); } // Set texture @@ -713,11 +713,11 @@ void CDriverGL3::setupNormalPass() if( t == NULL ) continue; - int index = pixelProgram->getUniformIndex( IProgram::EUniform( IProgram::Sampler0 + i ) ); + int index = currentProgram.pp->getUniformIndex( CProgramIndex::TName( CProgramIndex::Sampler0 + i ) ); if( index == -1 ) continue; - setUniform1i( IProgram::PIXEL_PROGRAM, index, i ); + setUniform1i( IDriver::PixelProgram, index, i ); } } @@ -894,18 +894,18 @@ void CDriverGL3::setupLightMapPass(uint pass) // setup constant color with Lightmap factor. stdEnv.ConstantColor=lmapFactor; - int cl = pixelProgram->getUniformIndex( IProgram::EUniform( IProgram::Constant0 + stage ) ); + int cl = currentProgram.pp->getUniformIndex( CProgramIndex::TName( CProgramIndex::Constant0 + stage ) ); if( cl != -1 ) { GLfloat glCol[ 4 ]; convColor( lmapFactor, glCol ); - setUniform4f( IProgram::PIXEL_PROGRAM, cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); + setUniform4f( IDriver::PixelProgram, cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); } - int tl = pixelProgram->getUniformIndex( IProgram::EUniform( IProgram::Sampler0 + stage ) ); + int tl = currentProgram.pp->getUniformIndex( CProgramIndex::TName( CProgramIndex::Sampler0 + stage ) ); if( tl != -1 ) { - setUniform1i( IProgram::PIXEL_PROGRAM, tl, stage ); + setUniform1i( IDriver::PixelProgram, tl, stage ); } activateTexEnvColor(stage, stdEnv); @@ -943,10 +943,10 @@ void CDriverGL3::setupLightMapPass(uint pass) _DriverGLStates.activeTextureARB(stage); _DriverGLStates.setTexGenMode(stage, 0); - int tl = pixelProgram->getUniformIndex( IProgram::EUniform( IProgram::Sampler0 + stage ) ); + int tl = currentProgram.pp->getUniformIndex( CProgramIndex::TName( CProgramIndex::Sampler0 + stage ) ); if( tl != -1 ) { - setUniform1i( IProgram::PIXEL_PROGRAM, tl, stage ); + setUniform1i( IDriver::PixelProgram, tl, stage ); } } @@ -1139,22 +1139,22 @@ void CDriverGL3::setupSpecularPass(uint pass) return; } - int sl0 = pixelProgram->getUniformIndex( IProgram::Sampler0 ); + int sl0 = currentProgram.pp->getUniformIndex( CProgramIndex::Sampler0 ); if( sl0 != -1 ) { - setUniform1i( IProgram::PIXEL_PROGRAM, sl0, 0 ); + setUniform1i( IDriver::PixelProgram, sl0, 0 ); } - int sl1 = pixelProgram->getUniformIndex( IProgram::Sampler1 ); + int sl1 = currentProgram.pp->getUniformIndex( CProgramIndex::Sampler1 ); if( sl1 != -1 ) { - setUniform1i( IProgram::PIXEL_PROGRAM, sl1, 1 ); + setUniform1i( IDriver::PixelProgram, sl1, 1 ); } - int tml = pixelProgram->getUniformIndex( IProgram::TexMatrix0 ); + int tml = currentProgram.vp->getUniformIndex( CProgramIndex::TexMatrix0 ); if( tml != -1 ) { - setUniformMatrix4fv( IProgram::PIXEL_PROGRAM, tml, 1, false, _UserTexMat[ 1 ].get() ); + setUniform4x4f( IDriver::VertexProgram, tml, _UserTexMat[ 1 ] ); } { diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp index dab30f6f9..f411389ff 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp @@ -15,9 +15,6 @@ // along with this program. If not, see . #include "driver_opengl.h" -#include "driver_glsl_program.h" -#include "driver_glsl_vertex_program.h" -#include "driver_glsl_pixel_program.h" #include "driver_glsl_shader_generator.h" #include "driver_opengl_vertex_buffer_hard.h" #include "nel/3d/dynamic_material.h" @@ -38,13 +35,32 @@ namespace namespace NL3D { - bool CDriverGL3::compileVertexProgram( CGLSLVertexProgram *program ) + bool CDriverGL3::supportVertexProgram(CVertexProgram::TProfile profile) const { - // Already compiled - if( program->getProgramId() != 0 ) + if( profile == IProgram::glsl330v ) return true; + else + return false; + } + + bool CDriverGL3::compileVertexProgram( CVertexProgram *program ) + { + if( program->m_DrvInfo != NULL ) + return false; + + IProgram::CSource *src = NULL; + for( int i = 0; i < program->getSourceNb(); i++ ) + { + src = program->getSource( i ); + if( src->Profile == IProgram::glsl330v ) + break; + + src = NULL; + } + if( src == NULL ) + return false; - const char *s = program->getSource().c_str(); + const char *s = src->SourcePtr; glGetError(); unsigned int id = nglCreateShaderProgramv( GL_VERTEX_SHADER, 1, &s ); @@ -66,19 +82,31 @@ namespace NL3D if( error != GL_NO_ERROR ) return false; - program->setProgramId( id ); + ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert( _GPUPrgDrvInfos.end(),(NL3D::IProgramDrvInfos*)NULL ); + CVertexProgramDrvInfosGL3 *drvInfo = new CVertexProgramDrvInfosGL3( this, it ); + + program->m_DrvInfo = drvInfo; + + drvInfo->setProgramId( id ); + + program->buildInfo( src ); return true; } - bool CDriverGL3::activeVertexProgram( CGLSLVertexProgram *program ) + bool CDriverGL3::activeVertexProgram( CVertexProgram *program ) { - if( program->getProgramId() == 0 ) + if( program == NULL ) + return true; + + IProgramDrvInfos *di = program->m_DrvInfo; + CVertexProgramDrvInfosGL3 *drvInfo = dynamic_cast< CVertexProgramDrvInfosGL3* >( di ); + if( drvInfo == NULL ) return false; glGetError(); - nglUseProgramStages( ppoId, GL_VERTEX_SHADER_BIT, program->getProgramId() ); + nglUseProgramStages( ppoId, GL_VERTEX_SHADER_BIT, drvInfo->getProgramId() ); GLenum error = glGetError(); if( error != GL_NO_ERROR ) @@ -87,18 +115,39 @@ namespace NL3D return false; } - vertexProgram = program; + currentProgram.vp = program; return true; } - bool CDriverGL3::compilePixelProgram( CGLSLPixelProgram *program ) + bool CDriverGL3::supportPixelProgram( IProgram::TProfile profile ) const { - // Already compiled - if( program->getProgramId() != 0 ) + if( profile == IProgram::glsl330f ) return true; + else + return false; + } - const char *s = program->getSource().c_str(); + bool CDriverGL3::compilePixelProgram( CPixelProgram *program ) + { + if( program->m_DrvInfo != NULL ) + return false; + + IProgram::CSource *src = NULL; + + for( int i = 0; i < program->getSourceNb(); i++ ) + { + src = program->getSource( i ); + if( src->Profile == IProgram::glsl330f ) + break; + + src = NULL; + } + + if( src == NULL ) + return false; + + const char *s = src->SourcePtr; glGetError(); unsigned int id = nglCreateShaderProgramv( GL_FRAGMENT_SHADER, 1, &s ); if( id == 0 ) @@ -118,19 +167,32 @@ namespace NL3D if( error != GL_NO_ERROR ) return false; - program->setProgramId( id ); + ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert( _GPUPrgDrvInfos.end(), ( NL3D::IProgramDrvInfos* )NULL ); + CPixelProgramDrvInfosGL3 *drvInfo = new CPixelProgramDrvInfosGL3( this, it ); + drvInfo->setProgramId( id ); + program->m_DrvInfo = drvInfo; + + program->buildInfo( src ); return true; } - bool CDriverGL3::activePixelProgram( CGLSLPixelProgram *program ) + bool CDriverGL3::activePixelProgram( CPixelProgram *program ) { - if( program->getProgramId() == 0 ) + if( program == NULL ) + return true; + + if( program->m_DrvInfo == NULL ) + return false; + + IProgramDrvInfos *di = program->m_DrvInfo; + CPixelProgramDrvInfosGL3 *drvInfo = dynamic_cast< CPixelProgramDrvInfosGL3* >( di ); + if( drvInfo == NULL ) return false; glGetError(); - nglUseProgramStages( ppoId, GL_FRAGMENT_SHADER_BIT, program->getProgramId() ); + nglUseProgramStages( ppoId, GL_FRAGMENT_SHADER_BIT, drvInfo->getProgramId() ); GLenum error = glGetError(); if( error != GL_NO_ERROR ) @@ -138,228 +200,237 @@ namespace NL3D return false; } - pixelProgram = program; + currentProgram.pp = program; return true; } - IProgram* CDriverGL3::createVertexProgram() const - { - return new CGLSLVertexProgram(); - } - IProgram* CDriverGL3::createPixelProgram() const + uint32 CDriverGL3::getProgramId( TProgram program ) const { - return new CGLSLPixelProgram(); - } + uint32 id = 0; - int CDriverGL3::getUniformLocation( uint32 programType, const char *name ) - { - switch( programType ) + switch( program ) { - case IProgram::VERTEX_PROGRAM: - nlassert( vertexProgram != NULL ); - return nglGetUniformLocation( vertexProgram->getProgramId(), name ); + case IDriver::VertexProgram: + { + if( currentProgram.vp != NULL ) + { + IProgramDrvInfos *di = currentProgram.vp->m_DrvInfo; + CVertexProgramDrvInfosGL3 *drvInfo = dynamic_cast< CVertexProgramDrvInfosGL3* >( di ); + if( drvInfo != NULL ) + id = drvInfo->getProgramId(); + } + } break; - case IProgram::PIXEL_PROGRAM: - nlassert( pixelProgram != NULL ); - return nglGetUniformLocation( pixelProgram->getProgramId(), name ); + case IDriver::PixelProgram: + if( currentProgram.pp != NULL ) + { + IProgramDrvInfos *di = currentProgram.pp->m_DrvInfo; + CPixelProgramDrvInfosGL3 *drvInfo = dynamic_cast< CPixelProgramDrvInfosGL3* >( di ); + if( drvInfo != NULL ) + id = drvInfo->getProgramId(); + } + break; + + case IDriver::GeometryProgram: break; } - return -1; + return id; } - - void CDriverGL3::setUniform1f( uint32 programType, uint index, float f ) + IProgram* CDriverGL3::getProgram( TProgram program ) const { - switch( programType ) + IProgram *p = NULL; + + switch( program ) { - case IProgram::VERTEX_PROGRAM: - nlassert( vertexProgram != NULL ); - nglProgramUniform1f( vertexProgram->getProgramId(), index, f ); + case IDriver::VertexProgram: + p = currentProgram.vp; break; - case IProgram::PIXEL_PROGRAM: - nlassert( pixelProgram != NULL ); - nglProgramUniform1f( pixelProgram->getProgramId(), index, f ); + + case IDriver::PixelProgram: + p = currentProgram.pp; break; - default: - nlassert( false ); + case IDriver::GeometryProgram: + p = currentProgram.gp; break; } + + return p; } - void CDriverGL3::setUniform3f( uint32 programType, uint index, float f1, float f2, float f3 ) + int CDriverGL3::getUniformLocation( TProgram program, const char *name ) { - switch( programType ) - { - case IProgram::VERTEX_PROGRAM: - nlassert( vertexProgram != NULL ); - nglProgramUniform3f( vertexProgram->getProgramId(), index, f1, f2, f3 ); - break; - case IProgram::PIXEL_PROGRAM: - nlassert( pixelProgram != NULL ); - nglProgramUniform3f( pixelProgram->getProgramId(), index, f1, f2, f3 ); - break; + uint32 id = getProgramId( program ); + return nglGetUniformLocation( id, name ); + } - default: - nlassert( false ); - break; - } + void CDriverGL3::setUniform1f( TProgram program, uint index, float f0 ) + { + uint32 id = getProgramId( program ); + nglProgramUniform1f( id, index, f0 ); } - void CDriverGL3::setUniform4f( uint32 programType, uint index, float f1, float f2, float f3, float f4 ) + void CDriverGL3::setUniform2f( TProgram program, uint index, float f0, float f1 ) { - switch( programType ) - { - case IProgram::VERTEX_PROGRAM: - nlassert( vertexProgram != NULL ); - nglProgramUniform4f( vertexProgram->getProgramId(), index, f1, f2, f3, f4 ); - break; - case IProgram::PIXEL_PROGRAM: - nlassert( pixelProgram != NULL ); - nglProgramUniform4f( pixelProgram->getProgramId(), index, f1, f2, f3, f4 ); - break; + uint32 id = getProgramId( program ); + nglProgramUniform2f( id, index, f0, f1 ); + } - default: - nlassert( false ); - break; - } + void CDriverGL3::setUniform3f( TProgram program, uint index, float f0, float f1, float f2 ) + { + uint32 id = getProgramId( program ); + nglProgramUniform3f( id, index, f0, f1, f2 ); } - void CDriverGL3::setUniform1i( uint32 programType, uint index, int i ) + void CDriverGL3::setUniform4f( TProgram program, uint index, float f0, float f1, float f2, float f3 ) { - switch( programType ) - { - case IProgram::VERTEX_PROGRAM: - nlassert( vertexProgram != NULL ); - nglProgramUniform1i( vertexProgram->getProgramId(), index, i ); - break; - case IProgram::PIXEL_PROGRAM: - nlassert( pixelProgram != NULL ); - nglProgramUniform1i( pixelProgram->getProgramId(), index, i ); - break; + uint32 id = getProgramId( program ); + nglProgramUniform4f( id, index, f0, f1, f2, f3 ); + } - default: - nlassert( false ); - break; - } + void CDriverGL3::setUniform1i( TProgram program, uint index, sint32 i0 ) + { + uint32 id = getProgramId( program ); + nglProgramUniform1i( id, index, i0 ); } - void CDriverGL3::setUniform4i( uint32 programType, uint index, int i1, int i2, int i3, int i4 ) + void CDriverGL3::setUniform2i( TProgram program, uint index, sint32 i0, sint32 i1 ) { - switch( programType ) - { - case IProgram::VERTEX_PROGRAM: - nlassert( vertexProgram != NULL ); - nglProgramUniform4i( vertexProgram->getProgramId(), index, i1, i2, i3, i4 ); - break; - case IProgram::PIXEL_PROGRAM: - nlassert( pixelProgram != NULL ); - nglProgramUniform4i( pixelProgram->getProgramId(), index, i1, i2, i3, i4 ); - break; + uint32 id = getProgramId( program ); + nglProgramUniform2i( id, index, i0, i1 ); + } - default: - nlassert( false ); - break; - } + void CDriverGL3::setUniform3i( TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2 ) + { + uint32 id = getProgramId( program ); + nglProgramUniform3i( id, index, i0, i1, i2 ); } - void CDriverGL3::setUniform1u( uint32 programType, uint index, uint u ) + void CDriverGL3::setUniform4i( TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3 ) { - switch( programType ) - { - case IProgram::VERTEX_PROGRAM: - nlassert( vertexProgram != NULL ); - nglProgramUniform1ui( vertexProgram->getProgramId(), index, u ); - break; - case IProgram::PIXEL_PROGRAM: - nlassert( pixelProgram != NULL ); - nglProgramUniform1ui( pixelProgram->getProgramId(), index, u ); - break; + uint32 id = getProgramId( program ); + nglProgramUniform4i( id, index, i0, i1, i2, i3 ); + } - default: - nlassert( false ); - break; - } + void CDriverGL3::setUniform1ui( TProgram program, uint index, uint32 ui0 ) + { + uint32 id = getProgramId( program ); + nglProgramUniform1ui( id, index, ui0 ); } - void CDriverGL3::setUniform4u( uint32 programType, uint index, uint u1, uint u2, uint u3, uint u4 ) + void CDriverGL3::setUniform2ui( TProgram program, uint index, uint32 ui0, uint32 ui1 ) { - switch( programType ) - { - case IProgram::VERTEX_PROGRAM: - nlassert( vertexProgram != NULL ); - nglProgramUniform4ui( vertexProgram->getProgramId(), index, u1, u2, u3, u4 ); - break; - case IProgram::PIXEL_PROGRAM: - nlassert( pixelProgram != NULL ); - nglProgramUniform4ui( pixelProgram->getProgramId(), index, u1, u2, u3, u4 ); - break; + uint32 id = getProgramId( program ); + nglProgramUniform2ui( id, index, ui0, ui1 ); + } - default: - nlassert( false ); - break; - } + void CDriverGL3::setUniform3ui( TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2 ) + { + uint32 id = getProgramId( program ); + nglProgramUniform3ui( id, index, ui0, ui1, ui2 ); } - void CDriverGL3::setUniformMatrix2fv( uint32 programType, uint index, uint count, bool transpose, const float *values ) + void CDriverGL3::setUniform4ui( TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3 ) { - switch( programType ) - { - case IProgram::VERTEX_PROGRAM: - nlassert( vertexProgram != NULL ); - nglProgramUniformMatrix2fv( vertexProgram->getProgramId(), index, count, transpose, values ); - break; - case IProgram::PIXEL_PROGRAM: - nlassert( pixelProgram != NULL ); - nglProgramUniformMatrix2fv( pixelProgram->getProgramId(), index, count, transpose, values ); - break; + uint32 id = getProgramId( program ); + nglProgramUniform4ui( id, index, ui0, ui1, ui2, ui3 ); + } - default: - nlassert( false ); - break; - } + void CDriverGL3::setUniform3f( TProgram program, uint index, const CVector &v ) + { + uint32 id = getProgramId( program ); + nglProgramUniform3f( id, index, v.x, v.y, v.z ); + } + + void CDriverGL3::setUniform4f( TProgram program, uint index, const CVector &v, float f3 ) + { + uint32 id = getProgramId( program ); + nglProgramUniform4f( id, index, v.x, v.y, v.z, f3 ); + } + + void CDriverGL3::setUniform4f( TProgram program, uint index, const NLMISC::CRGBAF& rgba ) + { + uint32 id = getProgramId( program ); + nglProgramUniform4f( id, index, rgba.R, rgba.G, rgba.B, rgba.A ); + } + + void CDriverGL3::setUniform4x4f( TProgram program, uint index, const CMatrix &m ) + { + uint32 id = getProgramId( program ); + nglProgramUniformMatrix4fv( id, index, 1, false, m.get() ); + } + + void CDriverGL3::setUniform4x4f( TProgram program, uint index, const float *src ) + { + uint32 id = getProgramId( program ); + nglProgramUniformMatrix4fv( id, index, 1, false, src ); + } + + void CDriverGL3::setUniform4fv( TProgram program, uint index, size_t num, const float *src ) + { + uint32 id = getProgramId( program ); + nglProgramUniform4fv( id, index, num, src ); + } + + void CDriverGL3::setUniform4iv( TProgram program, uint index, size_t num, const sint32 *src ) + { + uint32 id = getProgramId( program ); + nglProgramUniform4iv( id, index, num, src ); + } + + void CDriverGL3::setUniform4uiv( TProgram program, uint index, size_t num, const uint32 *src ) + { + uint32 id = getProgramId( program ); + nglProgramUniform4uiv( id, index, num, src ); } - void CDriverGL3::setUniformMatrix3fv( uint32 programType, uint index, uint count, bool transpose, const float *values ) + void CDriverGL3::setUniformMatrix( TProgram program, uint index, TMatrix matrix, TTransform transform ) { - switch( programType ) + uint32 id = getProgramId( program ); + CMatrix mat; + + + switch( matrix ) { - case IProgram::VERTEX_PROGRAM: - nlassert( vertexProgram != NULL ); - nglProgramUniformMatrix3fv( vertexProgram->getProgramId(), index, count, transpose, values ); + case IDriver::ModelView: + mat = _ModelViewMatrix; break; - case IProgram::PIXEL_PROGRAM: - nlassert( pixelProgram != NULL ); - nglProgramUniformMatrix3fv( pixelProgram->getProgramId(), index, count, transpose, values ); + case IDriver::Projection: + mat = _GLProjMat; break; - - default: - nlassert( false ); + case IDriver::ModelViewProjection: + mat = _ModelViewMatrix * _GLProjMat; break; } - } - void CDriverGL3::setUniformMatrix4fv( uint32 programType, uint index, uint count, bool transpose, const float *values ) - { - switch( programType ) + switch( transform ) { - case IProgram::VERTEX_PROGRAM: - nlassert( vertexProgram != NULL ); - nglProgramUniformMatrix4fv( vertexProgram->getProgramId(), index, count, transpose, values ); + case IDriver::Inverse: + mat.invert(); break; - case IProgram::PIXEL_PROGRAM: - nlassert( pixelProgram != NULL ); - nglProgramUniformMatrix4fv( pixelProgram->getProgramId(), index, count, transpose, values ); + case IDriver::Transpose: + mat.transpose(); break; - - default: - nlassert( false ); + case IDriver::InverseTranspose: + mat.transpose(); + mat.invert(); break; } + + + nglProgramUniformMatrix4fv( id, index, 1, false, mat.get() ); + } + + void CDriverGL3::setUniformFog( TProgram program, uint index ) + { + uint32 id = getProgramId( program ); + const float *v = _ModelViewMatrix.get(); + nglProgramUniform4f( id, index, -v[ 2 ], -v[ 6 ], -v[ 10 ], -v[ 4 ] ); } void CDriverGL3::generateShaderDesc( CShaderDesc &desc, CMaterial &mat ) @@ -428,8 +499,8 @@ namespace NL3D if( mat.getDynMat() != NULL ) return true; - CGLSLVertexProgram *vp = NULL; - CGLSLPixelProgram *pp = NULL; + CVertexProgram *vp = NULL; + CPixelProgram *pp = NULL; SShaderPair sp; CShaderDesc desc; @@ -458,8 +529,15 @@ namespace NL3D shaderGenerator->generateVS( vs ); shaderGenerator->generatePS( ps ); - vp = new CGLSLVertexProgram(); - vp->setSource( vs.c_str() ); + vp = new CVertexProgram(); + { + IProgram::CSource *src = new IProgram::CSource(); + src->Profile = IProgram::glsl330v; + src->DisplayName = ""; + src->setSource( vs ); + vp->addSource( src ); + } + if( !compileVertexProgram( vp ) ) { delete vp; @@ -467,8 +545,15 @@ namespace NL3D return false; } - pp = new CGLSLPixelProgram(); - pp->setSource( ps.c_str() ); + pp = new CPixelProgram(); + { + IProgram::CSource *src = new IProgram::CSource(); + src->Profile = IProgram::glsl330f; + src->DisplayName = ""; + src->setSource( ps ); + pp->addSource( src ); + } + if( !compilePixelProgram( pp ) ) { delete vp; @@ -496,8 +581,6 @@ namespace NL3D return false; } - vp->cacheUniforms(); - pp->cacheUniforms(); sp.vp = vp; sp.pp = pp; desc.setShaders( sp ); @@ -521,13 +604,23 @@ namespace NL3D if( !usrShaderManager->getShader( shaderRef, &prg ) ) return false; - CGLSLVertexProgram *vp = new CGLSLVertexProgram(); - CGLSLPixelProgram *pp = new CGLSLPixelProgram(); + CVertexProgram *vp = new CVertexProgram(); + CPixelProgram *pp = new CPixelProgram(); std::string shaderSource; std::string log; + std::string name; prg.getVP( shaderSource ); - vp->setSource( shaderSource.c_str() ); + prg.getName( name ); + + { + IProgram::CSource *src = new IProgram::CSource(); + src->Profile = IProgram::glsl330v; + src->DisplayName = name; + src->setSource( shaderSource.c_str() ); + vp->addSource( src ); + } + if( !compileVertexProgram( vp ) ) { delete vp; @@ -536,7 +629,14 @@ namespace NL3D } prg.getFP( shaderSource ); - pp->setSource( shaderSource.c_str() ); + { + IProgram::CSource *src = new IProgram::CSource(); + src->Profile = IProgram::glsl330f; + src->DisplayName = name; + src->setSource( shaderSource.c_str() ); + pp->addSource( src ); + } + if( !compilePixelProgram( pp ) ) { delete vp; @@ -558,16 +658,23 @@ namespace NL3D return false; } - if( dynMatVP != NULL ) - delete dynMatVP; - dynMatVP = vp; - - if( dynMatPP != NULL ) - delete dynMatPP; - dynMatPP = pp; + if( currentProgram.dynmatVP != NULL ) + { + ItGPUPrgDrvInfoPtrList itr = std::find( _GPUPrgDrvInfos.begin(), _GPUPrgDrvInfos.end(), currentProgram.dynmatVP->m_DrvInfo ); + if( itr != _GPUPrgDrvInfos.end() ) + _GPUPrgDrvInfos.erase( itr ); + delete currentProgram.dynmatVP; + } + currentProgram.dynmatVP = vp; - vp->cacheUniforms(); - pp->cacheUniforms(); + if( currentProgram.dynmatPP != NULL ) + { + ItGPUPrgDrvInfoPtrList itr = std::find( _GPUPrgDrvInfos.begin(), _GPUPrgDrvInfos.end(), currentProgram.dynmatPP->m_DrvInfo ); + if( itr != _GPUPrgDrvInfos.end() ) + _GPUPrgDrvInfos.erase( itr ); + delete currentProgram.dynmatPP; + } + currentProgram.dynmatPP = pp; return true; } @@ -575,27 +682,26 @@ namespace NL3D void CDriverGL3::setupUniforms() { - setupUniforms( vertexProgram ); - setupUniforms( pixelProgram ); + setupUniforms( IDriver::VertexProgram); + setupUniforms( IDriver::PixelProgram ); } - void CDriverGL3::setupUniforms( CGLSLProgram *program ) + void CDriverGL3::setupUniforms( TProgram program ) { CMaterial &mat = *_CurrentMaterial; - CGLSLProgram *currentProgram = program; - uint32 type = program->getType(); + IProgram *p = getProgram( program ); - int mvpIndex = currentProgram->getUniformIndex( IProgram::MVPMatrix ); + int mvpIndex = p->getUniformIndex( CProgramIndex::ModelViewProjection ); if( mvpIndex != -1 ) { - CMatrix mat = _GLProjMat * _ModelViewMatrix; - setUniformMatrix4fv( type, mvpIndex, 1, false, mat.get() ); + CMatrix mvp = _GLProjMat * _ModelViewMatrix; + setUniform4x4f( program, mvpIndex, mvp ); } - int mvIndex = currentProgram->getUniformIndex( IProgram::MVMatrix ); + int mvIndex = p->getUniformIndex( CProgramIndex::ModelView ); if( mvIndex != -1 ) { - setUniformMatrix4fv( type, mvIndex, 1, false, _ModelViewMatrix.get() ); + setUniform4x4f( program, mvIndex, _ModelViewMatrix ); } /* @@ -605,19 +711,19 @@ namespace NL3D } */ - int fogStartIdx = currentProgram->getUniformIndex( IProgram::FogStart ); + int fogStartIdx = p->getUniformIndex( CProgramIndex::FogStart ); if( fogStartIdx != -1 ) { - setUniform1f( type, fogStartIdx, getFogStart() ); + setUniform1f( program, fogStartIdx, getFogStart() ); } - int fogEndIdx = currentProgram->getUniformIndex( IProgram::FogEnd ); + int fogEndIdx = p->getUniformIndex( CProgramIndex::FogEnd ); if( fogEndIdx != -1 ) { - setUniform1f( type, fogEndIdx, getFogEnd() ); + setUniform1f( program, fogEndIdx, getFogEnd() ); } - int fogColorIdx = currentProgram->getUniformIndex( IProgram::FogColor ); + int fogColorIdx = p->getUniformIndex( CProgramIndex::FogColor ); if( fogColorIdx != -1 ) { GLfloat glCol[ 4 ]; @@ -626,10 +732,10 @@ namespace NL3D glCol[ 1 ] = col.G / 255.0f; glCol[ 2 ] = col.B / 255.0f; glCol[ 3 ] = col.A / 255.0f; - setUniform4f( type, fogColorIdx, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); + setUniform4f( program, fogColorIdx, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); } - int colorIndex = currentProgram->getUniformIndex( IProgram::Color ); + int colorIndex = p->getUniformIndex( CProgramIndex::Color ); if( colorIndex != -1 ) { GLfloat glCol[ 4 ]; @@ -639,10 +745,10 @@ namespace NL3D glCol[ 2 ] = col.B / 255.0f; glCol[ 3 ] = col.A / 255.0f; - setUniform4f( type, colorIndex, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); + setUniform4f( program, colorIndex, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); } - int diffuseIndex = currentProgram->getUniformIndex( IProgram::Diffuse ); + int diffuseIndex = p->getUniformIndex( CProgramIndex::DiffuseColor ); if( diffuseIndex != -1 ) { GLfloat glCol[ 4 ]; @@ -652,7 +758,7 @@ namespace NL3D glCol[ 2 ] = col.B / 255.0f; glCol[ 3 ] = col.A / 255.0f; - setUniform4f( type, diffuseIndex, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); + setUniform4f( program, diffuseIndex, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); } @@ -667,21 +773,26 @@ namespace NL3D continue; ////////////////////////////////////////////////////////////////////// - int ld = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0Dir + i ) ); - if( ld != -1 ) + if( _LightMode[ i ] == CLight::DirectionalLight ) { - CVector v = _UserLight[ i ].getDirection(); - setUniform3f( type, ld, v.x, v.y, v.z ); + int ld = p->getUniformIndex( CProgramIndex::TName( CProgramIndex::Light0DirOrPos + i ) ); + if( ld != -1 ) + { + CVector v = _UserLight[ i ].getDirection(); + setUniform3f( program, ld, v.x, v.y, v.z ); + } } - - int lp = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0Pos + i ) ); - if( lp != -1 ) + else { - CVector v = _UserLight[ i ].getPosition(); - setUniform3f( type, lp, v.x, v.y, v.z ); + int lp = p->getUniformIndex( CProgramIndex::TName( CProgramIndex::Light0DirOrPos + i ) ); + if( lp != -1 ) + { + CVector v = _UserLight[ i ].getPosition(); + setUniform3f( program, lp, v.x, v.y, v.z ); + } } - int ldc = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0ColDiff + i ) ); + int ldc = p->getUniformIndex( CProgramIndex::TName( CProgramIndex::Light0ColDiff + i ) ); if( ldc != -1 ) { GLfloat glCol[ 4 ]; @@ -690,10 +801,10 @@ namespace NL3D glCol[ 1 ] = col.G / 255.0f; glCol[ 2 ] = col.B / 255.0f; glCol[ 3 ] = col.A / 255.0f; - setUniform4f( type, ldc, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); + setUniform4f( program, ldc, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); } - int lsc = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0ColSpec + i ) ); + int lsc = p->getUniformIndex( CProgramIndex::TName( CProgramIndex::Light0ColSpec + i ) ); if( lsc != -1 ) { GLfloat glCol[ 4 ]; @@ -702,16 +813,16 @@ namespace NL3D glCol[ 1 ] = col.G / 255.0f; glCol[ 2 ] = col.B / 255.0f; glCol[ 3 ] = col.A / 255.0f; - setUniform4f( type, lsc, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); + setUniform4f( program, lsc, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); } - int shl = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0Shininess + i ) ); + int shl = p->getUniformIndex( CProgramIndex::TName( CProgramIndex::Light0Shininess + i ) ); if( shl != -1 ) { - setUniform1f( type, shl, mat.getShininess() ); + setUniform1f( program, shl, mat.getShininess() ); } - int lac = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0ColAmb + i ) ); + int lac = p->getUniformIndex( CProgramIndex::TName( CProgramIndex::Light0ColAmb + i ) ); if( lac != -1 ) { GLfloat glCol[ 4 ]; @@ -725,25 +836,25 @@ namespace NL3D glCol[ 1 ] = col.G / 255.0f; glCol[ 2 ] = col.B / 255.0f; glCol[ 3 ] = col.A / 255.0f; - setUniform4f( type, lac, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); + setUniform4f( program, lac, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); } - int lca = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0ConstAttn + i ) ); + int lca = p->getUniformIndex( CProgramIndex::TName( CProgramIndex::Light0ConstAttn + i ) ); if( lca != -1 ) { - setUniform1f( type, lca, _UserLight[ i ].getConstantAttenuation() ); + setUniform1f( program, lca, _UserLight[ i ].getConstantAttenuation() ); } - int lla = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0LinAttn + i ) ); + int lla = p->getUniformIndex( CProgramIndex::TName( CProgramIndex::Light0LinAttn + i ) ); if( lla != -1 ) { - setUniform1f( type, lla, _UserLight[ i ].getLinearAttenuation() ); + setUniform1f( program, lla, _UserLight[ i ].getLinearAttenuation() ); } - int lqa = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Light0QuadAttn + i ) ); + int lqa = p->getUniformIndex( CProgramIndex::TName( CProgramIndex::Light0QuadAttn + i ) ); if( lqa != -1 ) { - setUniform1f( type, lqa, _UserLight[ i ].getQuadraticAttenuation() ); + setUniform1f( program, lqa, _UserLight[ i ].getQuadraticAttenuation() ); } } @@ -754,7 +865,7 @@ namespace NL3D for( int i = 0; i < IDRV_MAT_MAXTEXTURES; i++ ) { - int cl = currentProgram->getUniformIndex( IProgram::EUniform( IProgram::Constant0 + i ) ); + int cl = p->getUniformIndex( CProgramIndex::TName( CProgramIndex::Constant0 + i ) ); if( cl != -1 ) { CRGBA col = mat._TexEnvs[ i ].ConstantColor; @@ -764,7 +875,7 @@ namespace NL3D glCol[ 2 ] = col.B / 255.0f; glCol[ 3 ] = col.A / 255.0f; - setUniform4f( type, cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); + setUniform4f( program, cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] ); } } diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_shader_desc.h b/code/nel/src/3d/driver/opengl3/driver_opengl_shader_desc.h index 90cd3ab9c..3942b9165 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_shader_desc.h +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_shader_desc.h @@ -24,8 +24,8 @@ namespace NL3D { - class CGLSLVertexProgram; - class CGLSLPixelProgram; + class CVertexProgram; + class CPixelProgram; struct SShaderPair { @@ -48,8 +48,8 @@ namespace NL3D return false; } - CGLSLVertexProgram *vp; - CGLSLPixelProgram *pp; + CVertexProgram *vp; + CPixelProgram *pp; }; class CShaderDesc diff --git a/code/nel/src/3d/driver_user.cpp b/code/nel/src/3d/driver_user.cpp index c3e494e7d..79f151aee 100644 --- a/code/nel/src/3d/driver_user.cpp +++ b/code/nel/src/3d/driver_user.cpp @@ -216,6 +216,12 @@ void CDriverUser::disableHardwareVertexProgram() _Driver->disableHardwareVertexProgram(); } +void CDriverUser::disableHardwarePixelProgram() +{ + NL3D_HAUTO_UI_DRIVER; + + _Driver->disableHardwarePixelProgram(); +} void CDriverUser::disableHardwareVertexArrayAGP() { NL3D_HAUTO_UI_DRIVER; @@ -1493,12 +1499,6 @@ void CDriverUser::forceTextureResize(uint divisor) _Driver->forceTextureResize(divisor); } -void CDriverUser::forceNativeFragmentPrograms(bool nativeOnly) -{ - NL3D_HAUTO_UI_DRIVER; - - _Driver->forceNativeFragmentPrograms(nativeOnly); -} bool CDriverUser::setMonitorColorProperties (const CMonitorColorProperties &properties) { NL3D_HAUTO_UI_DRIVER; diff --git a/code/nel/src/3d/flare_model.cpp b/code/nel/src/3d/flare_model.cpp index 47d9fdb43..6c422aac9 100644 --- a/code/nel/src/3d/flare_model.cpp +++ b/code/nel/src/3d/flare_model.cpp @@ -363,6 +363,8 @@ void CFlareModel::traverseRender() } // setup driver drv->activeVertexProgram(NULL); + drv->activePixelProgram(NULL); + drv->activeGeometryProgram(NULL); drv->setupModelMatrix(fs->getLookAtMode() ? CMatrix::Identity : getWorldMatrix()); // we don't change the fustrum to draw 2d shapes : it is costly, and we need to restore it after the drawing has been done // we setup Z to be (near + far) / 2, and setup x and y to get the screen coordinates we want @@ -565,6 +567,8 @@ void CFlareModel::updateOcclusionQueryBegin(IDriver *drv) { nlassert(drv); drv->activeVertexProgram(NULL); + drv->activePixelProgram(NULL); + drv->activeGeometryProgram(NULL); drv->setupModelMatrix(CMatrix::Identity); initStatics(); drv->setColorMask(false, false, false, false); // don't write any pixel during the test @@ -661,6 +665,8 @@ void CFlareModel::occlusionTest(CMesh &mesh, IDriver &drv) } drv.setColorMask(false, false, false, false); // don't write any pixel during the test drv.activeVertexProgram(NULL); + drv.activePixelProgram(NULL); + drv.activeGeometryProgram(NULL); setupOcclusionMeshMatrix(drv, *_Scene); drv.activeVertexBuffer(const_cast(mesh.getVertexBuffer())); // query drawn count diff --git a/code/nel/src/3d/geometry_program.cpp b/code/nel/src/3d/geometry_program.cpp new file mode 100644 index 000000000..26fb15ae9 --- /dev/null +++ b/code/nel/src/3d/geometry_program.cpp @@ -0,0 +1,49 @@ +/** \file geometry_program.cpp + * Geometry program definition + */ + +/* Copyright, 2000, 2001 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 "std3d.h" + +#include + +#include + +namespace NL3D +{ + +// *************************************************************************** + +CGeometryProgram::CGeometryProgram() +{ + +} + +// *************************************************************************** + +CGeometryProgram::~CGeometryProgram () +{ + +} + +// *************************************************************************** + +} // NL3D diff --git a/code/nel/src/3d/gpu_program_params.cpp b/code/nel/src/3d/gpu_program_params.cpp new file mode 100644 index 000000000..e196154f8 --- /dev/null +++ b/code/nel/src/3d/gpu_program_params.cpp @@ -0,0 +1,587 @@ +/** + * \file gpu_program_params.cpp + * \brief CGPUProgramParams + * \date 2013-09-07 22:17GMT + * \author Jan Boon (Kaetemi) + * CGPUProgramParams + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#include +#include + +// STL includes + +// NeL includes +// #include +#include +#include + +// Project includes +#include + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +CGPUProgramParams::CGPUProgramParams() : m_First(s_End), m_Last(s_End) +{ + +} + +CGPUProgramParams::~CGPUProgramParams() +{ + +} + +void CGPUProgramParams::copy(CGPUProgramParams *params) +{ + size_t offset = params->getBegin(); + while (offset != params->getEnd()) + { + uint index = params->getIndexByOffset(offset); + const std::string &name = params->getNameByOffset(offset); + size_t local; + uint size = params->getSizeByOffset(offset); + uint count = params->getCountByOffset(offset); + uint nbComponents = size * count; + if (index) + { + local = allocOffset(index, size, count, params->getTypeByOffset(offset)); + if (!name.empty()) + { + map(index, name); + } + } + else + { + nlassert(!name.empty()); + local = allocOffset(name, size, count, params->getTypeByOffset(offset)); + } + + uint32 *src = params->getPtrUIByOffset(offset); + uint32 *dst = getPtrUIByOffset(local); + + for (uint c = 0; c < nbComponents; ++c) + { + dst[c] = src[c]; + } + + offset = params->getNext(offset); + } +} + +void CGPUProgramParams::set1f(uint index, float f0) +{ + float *f = getPtrFByOffset(allocOffset(index, 1, 1, Float)); + f[0] = f0; +} + +void CGPUProgramParams::set2f(uint index, float f0, float f1) +{ + float *f = getPtrFByOffset(allocOffset(index, 2, 1, Float)); + f[0] = f0; + f[1] = f1; +} + +void CGPUProgramParams::set3f(uint index, float f0, float f1, float f2) +{ + float *f = getPtrFByOffset(allocOffset(index, 3, 1, Float)); + f[0] = f0; + f[1] = f1; + f[2] = f2; +} + +void CGPUProgramParams::set4f(uint index, float f0, float f1, float f2, float f3) +{ + float *f = getPtrFByOffset(allocOffset(index, 4, 1, Float)); + f[0] = f0; + f[1] = f1; + f[2] = f2; + f[3] = f3; +} + +void CGPUProgramParams::set1i(uint index, sint32 i0) +{ + sint32 *i = getPtrIByOffset(allocOffset(index, 1, 1, Int)); + i[0] = i0; +} + +void CGPUProgramParams::set2i(uint index, sint32 i0, sint32 i1) +{ + sint32 *i = getPtrIByOffset(allocOffset(index, 2, 1, Int)); + i[0] = i0; + i[1] = i1; +} + +void CGPUProgramParams::set3i(uint index, sint32 i0, sint32 i1, sint32 i2) +{ + sint32 *i = getPtrIByOffset(allocOffset(index, 3, 1, Int)); + i[0] = i0; + i[1] = i1; + i[2] = i2; +} + +void CGPUProgramParams::set4i(uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) +{ + sint32 *i = getPtrIByOffset(allocOffset(index, 4, 1, Int)); + i[0] = i0; + i[1] = i1; + i[2] = i2; + i[3] = i3; +} + +void CGPUProgramParams::set1ui(uint index, uint32 ui0) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(index, 1, 1, UInt)); + ui[0] = ui0; +} + +void CGPUProgramParams::set2ui(uint index, uint32 ui0, uint32 ui1) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(index, 2, 1, UInt)); + ui[0] = ui0; + ui[1] = ui1; +} + +void CGPUProgramParams::set3ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(index, 3, 1, UInt)); + ui[0] = ui0; + ui[1] = ui1; + ui[2] = ui2; +} + +void CGPUProgramParams::set4ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(index, 4, 1, UInt)); + ui[0] = ui0; + ui[1] = ui1; + ui[2] = ui2; + ui[3] = ui3; +} + +void CGPUProgramParams::set3f(uint index, const NLMISC::CVector& v) +{ + float *f = getPtrFByOffset(allocOffset(index, 3, 1, Float)); + f[0] = v.x; + f[1] = v.y; + f[2] = v.z; +} + +void CGPUProgramParams::set4f(uint index, const NLMISC::CVector& v, float f3) +{ + float *f = getPtrFByOffset(allocOffset(index, 4, 1, Float)); + f[0] = v.x; + f[1] = v.y; + f[2] = v.z; + f[3] = f3; +} + +void CGPUProgramParams::set4x4f(uint index, const NLMISC::CMatrix& m) +{ + // TODO: Verify this! + float *f = getPtrFByOffset(allocOffset(index, 4, 4, Float)); + NLMISC::CMatrix mt = m; + mt.transpose(); + mt.get(f); +} + +void CGPUProgramParams::set4fv(uint index, size_t num, const float *src) +{ + float *f = getPtrFByOffset(allocOffset(index, 4, num, Float)); + size_t nb = 4 * num; + for (uint c = 0; c < nb; ++c) + f[c] = src[c]; +} + +void CGPUProgramParams::set4iv(uint index, size_t num, const sint32 *src) +{ + sint32 *i = getPtrIByOffset(allocOffset(index, 4, num, Int)); + size_t nb = 4 * num; + for (uint c = 0; c < nb; ++c) + i[c] = src[c]; +} + +void CGPUProgramParams::set4uiv(uint index, size_t num, const uint32 *src) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(index, 4, num, UInt)); + size_t nb = 4 * num; + for (uint c = 0; c < nb; ++c) + ui[c] = src[c]; +} + +void CGPUProgramParams::unset(uint index) +{ + size_t offset = getOffset(index); + if (offset != getEnd()) + { + freeOffset(offset); + } +} + +void CGPUProgramParams::set1f(const std::string &name, float f0) +{ + float *f = getPtrFByOffset(allocOffset(name, 1, 1, Float)); + f[0] = f0; +} + +void CGPUProgramParams::set2f(const std::string &name, float f0, float f1) +{ + float *f = getPtrFByOffset(allocOffset(name, 2, 1, Float)); + f[0] = f0; + f[1] = f1; +} + +void CGPUProgramParams::set3f(const std::string &name, float f0, float f1, float f2) +{ + float *f = getPtrFByOffset(allocOffset(name, 3, 1, Float)); + f[0] = f0; + f[1] = f1; + f[2] = f2; +} + +void CGPUProgramParams::set4f(const std::string &name, float f0, float f1, float f2, float f3) +{ + float *f = getPtrFByOffset(allocOffset(name, 4, 1, Float)); + f[0] = f0; + f[1] = f1; + f[2] = f2; + f[3] = f3; +} + +void CGPUProgramParams::set1i(const std::string &name, sint32 i0) +{ + sint32 *i = getPtrIByOffset(allocOffset(name, 1, 1, Int)); + i[0] = i0; +} + +void CGPUProgramParams::set2i(const std::string &name, sint32 i0, sint32 i1) +{ + sint32 *i = getPtrIByOffset(allocOffset(name, 2, 1, Int)); + i[0] = i0; + i[1] = i1; +} + +void CGPUProgramParams::set3i(const std::string &name, sint32 i0, sint32 i1, sint32 i2) +{ + sint32 *i = getPtrIByOffset(allocOffset(name, 3, 1, Int)); + i[0] = i0; + i[1] = i1; + i[2] = i2; +} + +void CGPUProgramParams::set4i(const std::string &name, sint32 i0, sint32 i1, sint32 i2, sint32 i3) +{ + sint32 *i = getPtrIByOffset(allocOffset(name, 4, 1, Int)); + i[0] = i0; + i[1] = i1; + i[2] = i2; + i[3] = i3; +} + +void CGPUProgramParams::set1ui(const std::string &name, uint32 ui0) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(name, 1, 1, UInt)); + ui[0] = ui0; +} + +void CGPUProgramParams::set2ui(const std::string &name, uint32 ui0, uint32 ui1) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(name, 2, 1, UInt)); + ui[0] = ui0; + ui[1] = ui1; +} + +void CGPUProgramParams::set3ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(name, 3, 1, UInt)); + ui[0] = ui0; + ui[1] = ui1; + ui[2] = ui2; +} + +void CGPUProgramParams::set4ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(name, 4, 1, UInt)); + ui[0] = ui0; + ui[1] = ui1; + ui[2] = ui2; + ui[3] = ui3; +} + +void CGPUProgramParams::set3f(const std::string &name, const NLMISC::CVector& v) +{ + float *f = getPtrFByOffset(allocOffset(name, 3, 1, Float)); + f[0] = v.x; + f[1] = v.y; + f[2] = v.z; +} + +void CGPUProgramParams::set4f(const std::string &name, const NLMISC::CVector& v, float f3) +{ + float *f = getPtrFByOffset(allocOffset(name, 4, 1, Float)); + f[0] = v.x; + f[1] = v.y; + f[2] = v.z; + f[3] = f3; +} + +void CGPUProgramParams::set4x4f(const std::string &name, const NLMISC::CMatrix& m) +{ + // TODO: Verify this! + float *f = getPtrFByOffset(allocOffset(name, 4, 4, Float)); + NLMISC::CMatrix mt = m; + mt.transpose(); + mt.get(f); +} + +void CGPUProgramParams::set4fv(const std::string &name, size_t num, const float *src) +{ + float *f = getPtrFByOffset(allocOffset(name, 4, num, Float)); + size_t nb = 4 * num; + for (uint c = 0; c < nb; ++c) + f[c] = src[c]; +} + +void CGPUProgramParams::set4iv(const std::string &name, size_t num, const sint32 *src) +{ + sint32 *i = getPtrIByOffset(allocOffset(name, 4, num, Int)); + size_t nb = 4 * num; + for (uint c = 0; c < nb; ++c) + i[c] = src[c]; +} + +void CGPUProgramParams::set4uiv(const std::string &name, size_t num, const uint32 *src) +{ + uint32 *ui = getPtrUIByOffset(allocOffset(name, 4, num, UInt)); + size_t nb = 4 * num; + for (uint c = 0; c < nb; ++c) + ui[c] = src[c]; +} + +void CGPUProgramParams::unset(const std::string &name) +{ + size_t offset = getOffset(name); + if (offset != getEnd()) + { + freeOffset(offset); + } +} + +void CGPUProgramParams::map(uint index, const std::string &name) +{ + size_t offsetIndex = getOffset(index); + size_t offsetName = getOffset(name); + if (offsetName != getEnd()) + { + // Remove possible duplicate + if (offsetIndex != getEnd()) + { + freeOffset(offsetIndex); + } + + // Set index + m_Meta[offsetName].Index = index; + + // Map index to name + if (index >= m_Map.size()) + m_Map.resize(index + 1, s_End); + m_Map[index] = offsetName; + } + else if (offsetIndex != getEnd()) + { + // Set name + m_Meta[offsetIndex].Name = name; + + // Map name to index + m_MapName[name] = offsetIndex; + } +} + +/// Allocate specified number of components if necessary +size_t CGPUProgramParams::allocOffset(uint index, uint size, uint count, TType type) +{ + nlassert(count > 0); // this code will not properly handle 0 + nlassert(size > 0); // this code will not properly handle 0 + nlassert(index < 0xFFFF); // sanity check + + uint nbComponents = size * count; + size_t offset = getOffset(index); + if (offset != s_End) + { + if (getCountByOffset(offset) >= nbComponents) + { + m_Meta[offset].Type = type; + m_Meta[offset].Size = size; + m_Meta[offset].Count = count; + return offset; + } + if (getCountByOffset(offset) < nbComponents) + { + freeOffset(offset); + } + } + + // Allocate space + offset = allocOffset(size, count, type); + + // Fill + m_Meta[offset].Index = index; + + // Store offset in map + if (index >= m_Map.size()) + m_Map.resize(index + 1, s_End); + m_Map[index] = offset; + + return offset; +} + +/// Allocate specified number of components if necessary +size_t CGPUProgramParams::allocOffset(const std::string &name, uint size, uint count, TType type) +{ + nlassert(count > 0); // this code will not properly handle 0 + nlassert(size > 0); // this code will not properly handle 0 + nlassert(!name.empty()); // sanity check + + uint nbComponents = size * count; + size_t offset = getOffset(name); + if (offset != s_End) + { + if (getCountByOffset(offset) >= nbComponents) + { + m_Meta[offset].Type = type; + m_Meta[offset].Size = size; + m_Meta[offset].Count = count; + return offset; + } + if (getCountByOffset(offset) < nbComponents) + { + freeOffset(offset); + } + } + + // Allocate space + offset = allocOffset(size, count, type); + + // Fill + m_Meta[offset].Name = name; + + // Store offset in map + m_MapName[name] = offset; + + return offset; +} + +/// Allocate specified number of components if necessary +size_t CGPUProgramParams::allocOffset(uint size, uint count, TType type) +{ + uint nbComponents = size * count; + + // Allocate space + size_t offset = m_Meta.size(); + uint blocks = getNbRegistersByComponents(nbComponents); // per 4 components + m_Meta.resize(offset + blocks); + m_Vec.resize(offset + blocks); + + // Fill + m_Meta[offset].Size = size; + m_Meta[offset].Count = count; + m_Meta[offset].Type = type; + m_Meta[offset].Prev = m_Last; + m_Meta[offset].Next = s_End; + + // Link + if (m_Last == s_End) + { + m_First = m_Last = offset; + } + else + { + nlassert(m_Meta[m_Last].Next == s_End); // code error otherwise + m_Meta[m_Last].Next = offset; + m_Last = offset; + } + + return offset; +} + +/// Return offset for specified index +size_t CGPUProgramParams::getOffset(uint index) const +{ + if (index >= m_Map.size()) + return s_End; + return m_Map[index]; +} + +size_t CGPUProgramParams::getOffset(const std::string &name) const +{ + std::map::const_iterator it = m_MapName.find(name); + if (it == m_MapName.end()) + return s_End; + return it->second; +} + +/// Remove by offset +void CGPUProgramParams::freeOffset(size_t offset) +{ + uint index = getIndexByOffset(offset); + if (index != ~0) + { + if (m_Map.size() > index) + { + m_Map[index] = getEnd(); + } + } + const std::string &name = getNameByOffset(offset); + if (!name.empty()) + { + if (m_MapName.find(name) != m_MapName.end()) + { + m_MapName.erase(name); + } + } + if (offset == m_Last) + { + nlassert(m_Meta[offset].Next == s_End); + m_Last = m_Meta[offset].Prev; + } + else + { + nlassert(m_Meta[offset].Next != s_End); + m_Meta[m_Meta[offset].Next].Prev = m_Meta[offset].Prev; + } + if (offset == m_First) + { + nlassert(m_Meta[offset].Prev == s_End); + m_First = m_Meta[offset].Next; + } + else + { + nlassert(m_Meta[offset].Prev != s_End); + m_Meta[m_Meta[offset].Prev].Next = m_Meta[offset].Next; + } +} + +} /* namespace NL3D */ + +/* end of file */ diff --git a/code/nel/src/3d/i_program.cpp b/code/nel/src/3d/i_program.cpp deleted file mode 100644 index 740684369..000000000 --- a/code/nel/src/3d/i_program.cpp +++ /dev/null @@ -1,120 +0,0 @@ -// NeL - MMORPG Framework -// 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 . - - -#include "nel/3d/i_program.h" - -namespace NL3D -{ - const char *IProgram::uniformNames[ NUM_UNIFORMS ] = - { - "mvpMatrix", - "mvMatrix", - "normalMatrix", - "texMatrix0", - "texMatrix1", - "texMatrix2", - "texMatrix3", - "constant0", - "constant1", - "constant2", - "constant3", - "diffuse", - "mcolor", - "sampler0", - "sampler1", - "sampler2", - "sampler3", - "alphaTreshold", - "fogStart", - "fogEnd", - "fogColor", - "fogDensity", - "light0Dir", - "light1Dir", - "light2Dir", - "light3Dir", - "light4Dir", - "light5Dir", - "light6Dir", - "light7Dir", - "light0ColDiff", - "light1ColDiff", - "light2ColDiff", - "light3ColDiff", - "light4ColDiff", - "light5ColDiff", - "light6ColDiff", - "light7ColDiff", - "light0ColAmb", - "light1ColAmb", - "light2ColAmb", - "light3ColAmb", - "light4ColAmb", - "light5ColAmb", - "light6ColAmb", - "light7ColAmb", - "light0ColSpec", - "light1ColSpec", - "light2ColSpec", - "light3ColSpec", - "light4ColSpec", - "light5ColSpec", - "light6ColSpec", - "light7ColSpec", - "light0Shininess", - "light1Shininess", - "light2Shininess", - "light3Shininess", - "light4Shininess", - "light5Shininess", - "light6Shininess", - "light7Shininess", - "light0Pos", - "light1Pos", - "light2Pos", - "light3Pos", - "light4Pos", - "light5Pos", - "light6Pos", - "light7Pos", - "light0ConstAttn", - "light1ConstAttn", - "light2ConstAttn", - "light3ConstAttn", - "light4ConstAttn", - "light5ConstAttn", - "light6ConstAttn", - "light7ConstAttn", - "light0LinAttn", - "light1LinAttn", - "light2LinAttn", - "light3LinAttn", - "light4LinAttn", - "light5LinAttn", - "light6LinAttn", - "light7LinAttn", - "light0QuadAttn", - "light1QuadAttn", - "light2QuadAttn", - "light3QuadAttn", - "light4QuadAttn", - "light5QuadAttn", - "light6QuadAttn", - "light7QuadAttn" - }; -} - diff --git a/code/nel/src/3d/landscape.cpp b/code/nel/src/3d/landscape.cpp index 31f1bb051..154f6f847 100644 --- a/code/nel/src/3d/landscape.cpp +++ b/code/nel/src/3d/landscape.cpp @@ -568,18 +568,21 @@ void CLandscape::clear() void CLandscape::setDriver(IDriver *drv) { nlassert(drv); - if(_Driver != drv) + if (_Driver != drv) { _Driver= drv; // Does the driver support VertexShader??? // only if VP supported by GPU. - _VertexShaderOk= (_Driver->isVertexProgramSupported() && !_Driver->isVertexProgramEmulated()); + _VertexShaderOk = (!_Driver->isVertexProgramEmulated() && ( + _Driver->supportVertexProgram(CVertexProgram::nelvp) + // || _Driver->supportVertexProgram(CVertexProgram::glsl330v) // TODO_VP_GLSL + )); // Does the driver has sufficient requirements for Vegetable??? // only if VP supported by GPU, and Only if max vertices allowed. - _DriverOkForVegetable= _VertexShaderOk && (_Driver->getMaxVerticesByVertexBufferHard()>=(uint)NL3D_LANDSCAPE_VEGETABLE_MAX_AGP_VERTEX_MAX); + _DriverOkForVegetable = _VertexShaderOk && (_Driver->getMaxVerticesByVertexBufferHard()>=(uint)NL3D_LANDSCAPE_VEGETABLE_MAX_AGP_VERTEX_MAX); } } @@ -1193,20 +1196,33 @@ void CLandscape::render(const CVector &refineCenter, const CVector &frontVecto // If VertexShader enabled, setup VertexProgram Constants. - if(_VertexShaderOk) + if (_VertexShaderOk) { - // c[0..3] take the ModelViewProjection Matrix. - driver->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); - // c[4] take useful constants. - driver->setConstant(4, 0, 1, 0.5f, 0); - // c[5] take RefineCenter - driver->setConstant(5, refineCenter); - // c[6] take info for Geomorph trnasition to TileNear. - driver->setConstant(6, CLandscapeGlobals::TileDistFarSqr, CLandscapeGlobals::OOTileDistDeltaSqr, 0, 0); - // c[10] take the fog vector. - driver->setConstantFog(10); - // c[12] take the current landscape Center / delta Pos to apply - driver->setConstant(12, _PZBModelPosition); + bool uprogstate = driver->isUniformProgramState(); + uint nbvp = uprogstate ? CLandscapeVBAllocator::MaxVertexProgram : 1; + for (uint i = 0; i < nbvp; ++i) + { + CVertexProgramLandscape *program = _TileVB.getVP(i); + if (program) + { + // activate the program to set the uniforms in the program state for all programs + // note: when uniforms are driver state, the indices must be the same across programs + _TileVB.activateVP(i); + + // c[0..3] take the ModelViewProjection Matrix. + driver->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); + // c[4] take useful constants. + driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants0, 0, 1, 0.5f, 0); + // c[5] take RefineCenter + driver->setUniform3f(IDriver::VertexProgram, program->idx().RefineCenter, refineCenter); + // c[6] take info for Geomorph trnasition to TileNear. + driver->setUniform2f(IDriver::VertexProgram, program->idx().TileDist, CLandscapeGlobals::TileDistFarSqr, CLandscapeGlobals::OOTileDistDeltaSqr); + // c[10] take the fog vector. + driver->setUniformFog(IDriver::VertexProgram, program->getUniformIndex(CProgramIndex::Fog)); + // c[12] take the current landscape Center / delta Pos to apply + driver->setUniform3f(IDriver::VertexProgram, program->idx().PZBModelPosition, _PZBModelPosition); + } + } } diff --git a/code/nel/src/3d/landscapevb_allocator.cpp b/code/nel/src/3d/landscapevb_allocator.cpp index 00cf78f1f..2c30cc19b 100644 --- a/code/nel/src/3d/landscapevb_allocator.cpp +++ b/code/nel/src/3d/landscapevb_allocator.cpp @@ -82,7 +82,10 @@ void CLandscapeVBAllocator::updateDriver(IDriver *driver) deleteVertexProgram(); // Then rebuild VB format, and VertexProgram, if needed. // Do it only if VP supported by GPU. - setupVBFormatAndVertexProgram(_Driver->isVertexProgramSupported() && !_Driver->isVertexProgramEmulated()); + setupVBFormatAndVertexProgram(!_Driver->isVertexProgramEmulated() && ( + _Driver->supportVertexProgram(CVertexProgram::nelvp) + // || _Driver->supportVertexProgram(CVertexProgram::glsl330v) // TODO_VP_GLSL + )); // must reallocate the VertexBuffer. if( _NumVerticesAllocated>0 ) @@ -247,14 +250,23 @@ void CLandscapeVBAllocator::activate(uint vpId) nlassert(_Driver); nlassert(!_BufferLocked); + activateVP(vpId); + + _Driver->activeVertexBuffer(_VB); +} + + +// *************************************************************************** +void CLandscapeVBAllocator::activateVP(uint vpId) +{ + nlassert(_Driver); + // If enabled, activate Vertex program first. - if(_VertexProgram[vpId]) + if (_VertexProgram[vpId]) { //nlinfo("\nSTARTVP\n%s\nENDVP\n", _VertexProgram[vpId]->getProgram().c_str()); nlverify(_Driver->activeVertexProgram(_VertexProgram[vpId])); } - - _Driver->activeVertexBuffer(_VB); } @@ -516,12 +528,11 @@ const char* NL3D_LandscapeTileLightMapEndProgram= // *************************************************************************** void CLandscapeVBAllocator::deleteVertexProgram() { - for(uint i=0;icompileVertexProgram(_VertexProgram[0])); } else if(_Type==Far1) { @@ -577,9 +587,8 @@ void CLandscapeVBAllocator::setupVBFormatAndVertexProgram(bool withVertexProgr _VB.initEx(); // Init the Vertex Program. - string vpgram= string(NL3D_LandscapeCommonStartProgram) + - string(NL3D_LandscapeFar1EndProgram); - _VertexProgram[0]= new CVertexProgram(vpgram.c_str()); + _VertexProgram[0] = new CVertexProgramLandscape(Far1); + nlverify(_Driver->compileVertexProgram(_VertexProgram[0])); } else { @@ -594,20 +603,76 @@ void CLandscapeVBAllocator::setupVBFormatAndVertexProgram(bool withVertexProgr _VB.initEx(); // Init the Vertex Program. - string vpgram= string(NL3D_LandscapeCommonStartProgram) + - string(NL3D_LandscapeTileEndProgram); - _VertexProgram[0]= new CVertexProgram(vpgram.c_str()); + _VertexProgram[0] = new CVertexProgramLandscape(Tile, false); + nlverify(_Driver->compileVertexProgram(_VertexProgram[0])); // Init the Vertex Program for lightmap pass - vpgram= string(NL3D_LandscapeCommonStartProgram) + - string(NL3D_LandscapeTileLightMapEndProgram); - _VertexProgram[1]= new CVertexProgram(vpgram.c_str()); + _VertexProgram[1] = new CVertexProgramLandscape(Tile, true); + nlverify(_Driver->compileVertexProgram(_VertexProgram[1])); } } } +CVertexProgramLandscape::CVertexProgramLandscape(CLandscapeVBAllocator::TType type, bool lightMap) +{ + // nelvp + { + CSource *source = new CSource(); + source->Profile = nelvp; + source->DisplayName = "Landscape/nelvp"; + switch (type) + { + case CLandscapeVBAllocator::Far0: + source->DisplayName += "/far0"; + source->setSource(std::string(NL3D_LandscapeCommonStartProgram) + + std::string(NL3D_LandscapeFar0EndProgram)); + break; + case CLandscapeVBAllocator::Far1: + source->DisplayName += "/far1"; + source->setSource(std::string(NL3D_LandscapeCommonStartProgram) + + std::string(NL3D_LandscapeFar1EndProgram)); + break; + case CLandscapeVBAllocator::Tile: + source->DisplayName += "/tile"; + if (lightMap) + { + source->DisplayName += "/lightmap"; + source->setSource(std::string(NL3D_LandscapeCommonStartProgram) + + std::string(NL3D_LandscapeTileLightMapEndProgram)); + } + else + { + source->setSource(std::string(NL3D_LandscapeCommonStartProgram) + + std::string(NL3D_LandscapeTileEndProgram)); + } + break; + } + source->ParamIndices["modelViewProjection"] = 0; + source->ParamIndices["programConstants0"] = 4; + source->ParamIndices["refineCenter"] = 5; + source->ParamIndices["tileDist"] = 6; + source->ParamIndices["fog"] = 10; + source->ParamIndices["pzbModelPosition"] = 12; + addSource(source); + } + // TODO_VP_GLSL + { + // .... + } +} +void CVertexProgramLandscape::buildInfo() +{ + m_Idx.ProgramConstants0 = getUniformIndex("programConstants0"); + nlassert(m_Idx.ProgramConstants0 != ~0); + m_Idx.RefineCenter = getUniformIndex("refineCenter"); + nlassert(m_Idx.RefineCenter != ~0); + m_Idx.TileDist = getUniformIndex("tileDist"); + nlassert(m_Idx.TileDist != ~0); + m_Idx.PZBModelPosition = getUniformIndex("pzbModelPosition"); + nlassert(m_Idx.PZBModelPosition != ~0); +} } // NL3D diff --git a/code/nel/src/3d/lod_character_shape.cpp b/code/nel/src/3d/lod_character_shape.cpp index 09aded766..6250f2fb5 100644 --- a/code/nel/src/3d/lod_character_shape.cpp +++ b/code/nel/src/3d/lod_character_shape.cpp @@ -264,9 +264,9 @@ void CLodCharacterShapeBuild::compile(const std::vector &triangleSelection void CLodCharacterShapeBuild::serial(NLMISC::IStream &f) { // NEL_CLODBULD - f.serialCheck((uint32)'_LEN'); - f.serialCheck((uint32)'DOLC'); - f.serialCheck((uint32)'DLUB'); + f.serialCheck(NELID("_LEN")); + f.serialCheck(NELID("DOLC")); + f.serialCheck(NELID("DLUB")); /* Version 1: @@ -525,9 +525,9 @@ void CLodCharacterShape::CBoneInfluence::serial(NLMISC::IStream &f) void CLodCharacterShape::serial(NLMISC::IStream &f) { // NEL_CLODSHAP - f.serialCheck((uint32)'_LEN'); - f.serialCheck((uint32)'DOLC'); - f.serialCheck((uint32)'PAHS'); + f.serialCheck(NELID("_LEN")); + f.serialCheck(NELID("DOLC")); + f.serialCheck(NELID("PAHS")); /* Version 1: diff --git a/code/nel/src/3d/material.cpp b/code/nel/src/3d/material.cpp index a6b17eeb5..2d05cd292 100644 --- a/code/nel/src/3d/material.cpp +++ b/code/nel/src/3d/material.cpp @@ -18,7 +18,6 @@ #include "nel/3d/material.h" #include "nel/3d/texture.h" -#include "nel/3d/shader.h" #include "nel/3d/driver.h" #include "nel/3d/dynamic_material.h" #include "nel/3d/texture_file.h" diff --git a/code/nel/src/3d/meshvp_per_pixel_light.cpp b/code/nel/src/3d/meshvp_per_pixel_light.cpp index fe4e94f8f..0fd2353a4 100644 --- a/code/nel/src/3d/meshvp_per_pixel_light.cpp +++ b/code/nel/src/3d/meshvp_per_pixel_light.cpp @@ -32,14 +32,13 @@ namespace NL3D { -std::auto_ptr CMeshVPPerPixelLight::_VertexProgram[NumVp]; + +NLMISC::CSmartPtr CMeshVPPerPixelLight::_VertexProgram[NumVp]; // *************************************************************************** // Light VP fragment constants start at 24 static const uint VPLightConstantStart = 24; - - // *************************************************************************** // *************************************************************************** @@ -355,18 +354,36 @@ static const char* PPLightingVPCodeTest = "; ***************************************************************/ - - - -//================================================================================= -void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi) +class CVertexProgramPerPixelLight : public CVertexProgramLighted { - // init the vertexProgram code. - static bool vpCreated= false; - if(!vpCreated) +public: + struct CIdx { - vpCreated= true; + /// Position or direction of strongest light + uint StrongestLight; + /// Viewer position + uint ViewerPos; + }; + CVertexProgramPerPixelLight(uint vp); + virtual ~CVertexProgramPerPixelLight() { }; + virtual void buildInfo(); + const CIdx &idx() const { return m_Idx; } + +private: + CIdx m_Idx; + +}; + +CVertexProgramPerPixelLight::CVertexProgramPerPixelLight(uint vp) +{ + // lighted settings + m_FeaturesLighted.SupportSpecular = (vp & 2) != 0; + m_FeaturesLighted.NumActivePointLights = MaxLight - 1; + m_FeaturesLighted.Normalize = false; + m_FeaturesLighted.CtStartNeLVP = VPLightConstantStart; + // nelvp + { // Gives each vp name // Bit 0 : 1 when it is a directionnal light // Bit 1 : 1 when specular is needed @@ -389,34 +406,89 @@ void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi) }; uint numvp = sizeof(vpName) / sizeof(const char *); - nlassert(NumVp == numvp); // make sure that it is in sync with header..todo : compile time assert :) - for (uint vp = 0; vp < NumVp; ++vp) + nlassert(CMeshVPPerPixelLight::NumVp == numvp); // make sure that it is in sync with header..todo : compile time assert :) + + // \todo yoyo TODO_OPTIM Manage different number of pointLights + // NB: never call getLightVPFragmentNeLVP() with normalize, because already done by PerPixel fragment before. + std::string vpCode = std::string(vpName[vp]) + + std::string("# ***************") // temp for debug + + CRenderTrav::getLightVPFragmentNeLVP( + m_FeaturesLighted.NumActivePointLights, + m_FeaturesLighted.CtStartNeLVP, + m_FeaturesLighted.SupportSpecular, + m_FeaturesLighted.Normalize) + + std::string("# ***************") // temp for debug + + std::string(PPLightingVPCodeEnd); + #ifdef NL_DEBUG + /** For test : parse those programs before they are used. + * As a matter of fact some program will works with the NV_VERTEX_PROGRAM extension, + * but won't with EXT_vertex_shader, because there are some limitations (can't read a temp + * register that hasn't been written before..) + */ + CVPParser vpParser; + CVPParser::TProgram result; + std::string parseOutput; + if (!vpParser.parse(vpCode.c_str(), result, parseOutput)) + { + nlwarning(parseOutput.c_str()); + nlassert(0); + } + #endif + + CSource *source = new CSource(); + source->DisplayName = NLMISC::toString("nelvp/MeshVPPerPixel/%i", vp); + source->Profile = CVertexProgram::nelvp; + source->setSource(vpCode); + source->ParamIndices["modelViewProjection"] = 0; + addSource(source); + } + + // glsl + { + // TODO_VP_GLSL + } +} + +void CVertexProgramPerPixelLight::buildInfo() +{ + CVertexProgramLighted::buildInfo(); + if (profile() == nelvp) + { + m_Idx.StrongestLight = 4; + if (m_FeaturesLighted.SupportSpecular) + { + m_Idx.ViewerPos = 5; + } + else { - // \todo yoyo TODO_OPTIM Manage different number of pointLights - // NB: never call getLightVPFragment() with normalize, because already done by PerPixel fragment before. - std::string vpCode = std::string(vpName[vp]) - + std::string("# ***************") // temp for debug - + CRenderTrav::getLightVPFragment(CRenderTrav::MaxVPLight-1, VPLightConstantStart, (vp & 2) != 0, false) - + std::string("# ***************") // temp for debug - + std::string(PPLightingVPCodeEnd); - #ifdef NL_DEBUG - /** For test : parse those programs before they are used. - * As a matter of fact some program will works with the NV_VERTEX_PROGRAM extension, - * but won't with EXT_vertex_shader, because there are some limitations (can't read a temp - * register that hasn't been written before..) - */ - CVPParser vpParser; - CVPParser::TProgram result; - std::string parseOutput; - if (!vpParser.parse(vpCode.c_str(), result, parseOutput)) - { - nlwarning(parseOutput.c_str()); - nlassert(0); - } - #endif - _VertexProgram[vp]= std::auto_ptr(new CVertexProgram(vpCode.c_str())); + m_Idx.ViewerPos = ~0; } + } + else + { + // TODO_VP_GLSL + } + nlassert(m_Idx.StrongestLight != ~0); + if (m_FeaturesLighted.SupportSpecular) + { + nlassert(m_Idx.ViewerPos != ~0); + } +} + +//================================================================================= +void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi) +{ + // init the vertexProgram code. + static bool vpCreated= false; + if (!vpCreated) + { + vpCreated = true; + + for (uint vp = 0; vp < NumVp; ++vp) + { + _VertexProgram[vp] = new CVertexProgramPerPixelLight(vp); + } } } @@ -427,21 +499,24 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv, const NLMISC::CVector &viewerPos) { // test if supported by driver - if (! - (drv->isVertexProgramSupported() - && !drv->isVertexProgramEmulated() - && drv->supportPerPixelLighting(SpecularLighting) - ) - ) + if (drv->isVertexProgramEmulated() + || !drv->supportPerPixelLighting(SpecularLighting)) + { + return false; + } + // + enable(true, drv); // must enable the vertex program before the vb is activated + CVertexProgramPerPixelLight *program = _ActiveVertexProgram; + if (!program) { + // failed to compile vertex program return false; } // CRenderTrav *renderTrav= &scene->getRenderTrav(); /// Setup for gouraud lighting - renderTrav->beginVPLightSetup(VPLightConstantStart, - SpecularLighting, - invertedModelMat); + renderTrav->prepareVPLightSetup(); + renderTrav->beginVPLightSetup(program, invertedModelMat); // sint strongestLightIndex = renderTrav->getStrongestLightIndex(); if (strongestLightIndex == -1) return false; // if no strongest light, disable this vertex program @@ -455,7 +530,7 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv, { // put light direction in object space NLMISC::CVector lPos = invertedModelMat.mulVector(strongestLight.getDirection()); - drv->setConstant(4, lPos); + drv->setUniform3f(IDriver::VertexProgram, program->idx().StrongestLight, lPos); _IsPointLight = false; } break; @@ -463,7 +538,7 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv, { // put light in object space NLMISC::CVector lPos = invertedModelMat * strongestLight.getPosition(); - drv->setConstant(4, lPos); + drv->setUniform3f(IDriver::VertexProgram, program->idx().StrongestLight, lPos); _IsPointLight = true; } break; @@ -477,14 +552,12 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv, { // viewer pos in object space NLMISC::CVector vPos = invertedModelMat * viewerPos; - drv->setConstant(5, vPos); + drv->setUniform3f(IDriver::VertexProgram, program->idx().ViewerPos, vPos); } // c[0..3] take the ModelViewProjection Matrix. After setupModelMatrix(); - drv->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); - // - enable(true, drv); // must enable the vertex program before the vb is activated - // + drv->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); + return true; } @@ -521,11 +594,19 @@ void CMeshVPPerPixelLight::enable(bool enabled, IDriver *drv) | (SpecularLighting ? 2 : 0) | (_IsPointLight ? 1 : 0); // - drv->activeVertexProgram(_VertexProgram[idVP].get()); + if (drv->activeVertexProgram((CVertexProgramPerPixelLight *)_VertexProgram[idVP])) + { + _ActiveVertexProgram = _VertexProgram[idVP]; + } + else + { + _ActiveVertexProgram = NULL; + } } else { drv->activeVertexProgram(NULL); + _ActiveVertexProgram = NULL; } _Enabled = enabled; } @@ -538,6 +619,8 @@ bool CMeshVPPerPixelLight::setupForMaterial(const CMaterial &mat, ) { bool enabled = (mat.getShader() == CMaterial::PerPixelLighting || mat.getShader() == CMaterial::PerPixelLightingNoSpec); + bool change = (enabled != _Enabled); + enable(enabled, drv); // enable disable the vertex program (for material that don't have the right shader) if (enabled) { CRenderTrav *renderTrav= &scene->getRenderTrav(); @@ -547,8 +630,6 @@ bool CMeshVPPerPixelLight::setupForMaterial(const CMaterial &mat, renderTrav->getStrongestLightColors(pplDiffuse, pplSpecular); drv->setPerPixelLightingLight(pplDiffuse, pplSpecular, mat.getShininess()); } - bool change = (enabled != _Enabled); - enable(enabled, drv); // enable disable the vertex program (for material that don't have the right shader) return change; } //================================================================================= diff --git a/code/nel/src/3d/meshvp_wind_tree.cpp b/code/nel/src/3d/meshvp_wind_tree.cpp index bf04c6096..0d2e91363 100644 --- a/code/nel/src/3d/meshvp_wind_tree.cpp +++ b/code/nel/src/3d/meshvp_wind_tree.cpp @@ -35,11 +35,11 @@ namespace NL3D // *************************************************************************** // Light VP fragment constants start at 24 -static const uint VPLightConstantStart= 24; +static const uint VPLightConstantStart = 24; // *************************************************************************** -std::auto_ptr CMeshVPWindTree::_VertexProgram[CMeshVPWindTree::NumVp]; +NLMISC::CSmartPtr CMeshVPWindTree::_VertexProgram[CMeshVPWindTree::NumVp]; static const char* WindTreeVPCodeWave= "!!VP1.0 \n\ @@ -79,6 +79,83 @@ static const char* WindTreeVPCodeEnd= END \n\ "; + +class CVertexProgramWindTree : public CVertexProgramLighted +{ +public: + struct CIdx + { + uint ProgramConstants[3]; + uint WindLevel1; + uint WindLevel2[4]; + uint WindLevel3[4]; + }; + CVertexProgramWindTree(uint numPls, bool specular, bool normalize); + virtual ~CVertexProgramWindTree() { }; + virtual void buildInfo(); + const CIdx &idx() const { return m_Idx; } + + bool PerMeshSetup; + +private: + CIdx m_Idx; + +}; + +CVertexProgramWindTree::CVertexProgramWindTree(uint numPls, bool specular, bool normalize) +{ + // lighted settings + m_FeaturesLighted.SupportSpecular = specular; + m_FeaturesLighted.NumActivePointLights = numPls; + m_FeaturesLighted.Normalize = normalize; + m_FeaturesLighted.CtStartNeLVP = VPLightConstantStart; + + // constants cache + PerMeshSetup = false; + + // nelvp + { + std::string vpCode = std::string(WindTreeVPCodeWave) + + CRenderTrav::getLightVPFragmentNeLVP(numPls, VPLightConstantStart, specular, normalize) + + WindTreeVPCodeEnd; + + CSource *source = new CSource(); + source->DisplayName = NLMISC::toString("nelvp/MeshVPWindTree/%i/%s/%s", numPls, specular ? "spec" : "nospec", normalize ? "normalize" : "nonormalize"); + source->Profile = CVertexProgram::nelvp; + source->setSource(vpCode); + source->ParamIndices["modelViewProjection"] = 0; + source->ParamIndices["fog"] = 6; + addSource(source); + } + + // TODO_VP_GLSL +} + +void CVertexProgramWindTree::buildInfo() +{ + CVertexProgramLighted::buildInfo(); + if (profile() == nelvp) + { + m_Idx.ProgramConstants[0] = 8; + m_Idx.ProgramConstants[1] = 9; + m_Idx.ProgramConstants[2] = 10; + m_Idx.WindLevel1 = 15; + m_Idx.WindLevel2[0] = 16; + m_Idx.WindLevel2[1] = 17; + m_Idx.WindLevel2[2] = 18; + m_Idx.WindLevel2[3] = 19; + m_Idx.WindLevel3[0] = 20; + m_Idx.WindLevel3[1] = 21; + m_Idx.WindLevel3[2] = 22; + m_Idx.WindLevel3[3] = 23; + } + else + { + // TODO_VP_GLSL + } +} + + // *************************************************************************** float CMeshVPWindTree::speedCos(float angle) { @@ -130,21 +207,17 @@ void CMeshVPWindTree::serial(NLMISC::IStream &f) throw(NLMISC::EStream) f.serial(SpecularLighting); } - -// *************************************************************************** -void CMeshVPWindTree::initInstance(CMeshBaseInstance *mbi) +void CMeshVPWindTree::initVertexPrograms() { // init the vertexProgram code. static bool vpCreated= false; + if(!vpCreated) { vpCreated= true; // All vpcode and begin() written for HrcDepth==3 nlassert(HrcDepth==3); - // combine fragments. - string vpCode; - // For all possible VP. for(uint i=0;i(new CVertexProgram(vpCode.c_str())); + // combine + _VertexProgram[i] = new CVertexProgramWindTree(numPls, normalize, specular); } } +} + +// *************************************************************************** +void CMeshVPWindTree::initInstance(CMeshBaseInstance *mbi) +{ + initVertexPrograms(); // init a random phase. mbi->_VPWindTreePhase= frand(1); @@ -203,21 +279,27 @@ inline void CMeshVPWindTree::setupPerMesh(IDriver *driver, CScene *scene) } } + CVertexProgramWindTree *program = _ActiveVertexProgram; + nlassert(program); + // Setup common constants for each instances. // c[8] take useful constants. - static float ct8[4]= {0, 1, 0.5f, 2}; - driver->setConstant(8, 1, ct8); + driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants[0], + 0, 1, 0.5f, 2); // c[9] take other useful constants. - static float ct9[4]= {3.f, 0.f, -1.f, -2.f}; - driver->setConstant(9, 1, ct9); + driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants[1], + 3.f, 0.f, -1.f, -2.f); // c[10] take Number of phase (4) for level2 and 3. -0.01 to avoid int value == 4. - static float ct10[4]= {4-0.01f, 0, 0, 0}; - driver->setConstant(10, 1, ct10); + driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants[2], + 4-0.01f, 0, 0, 0); } // *************************************************************************** inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene *scene, CMeshBaseInstance *mbi, const NLMISC::CMatrix &invertedModelMat) { + CVertexProgramWindTree *program = _ActiveVertexProgram; + nlassert(program); + // get instance info float instancePhase= mbi->_VPWindTreePhase; @@ -238,16 +320,18 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene setupLighting(scene, mbi, invertedModelMat); // c[0..3] take the ModelViewProjection Matrix. After setupModelMatrix(); - driver->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); + driver->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CProgramIndex::ModelViewProjection), + IDriver::ModelViewProjection, IDriver::Identity); // c[4..7] take the ModelView Matrix. After setupModelMatrix();00 - driver->setConstantFog(6); + driver->setUniformFog(IDriver::VertexProgram, program->getUniformIndex(CProgramIndex::Fog)); // c[15] take Wind of level 0. float f; f= _CurrentTime[0] + instancePhase; f= speedCos(f) + Bias[0]; - driver->setConstant(15, maxDeltaPosOS[0]*f ); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel1, + maxDeltaPosOS[0]*f ); // c[16-19] take Wind of level 1. @@ -255,16 +339,20 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene float instTime1= _CurrentTime[1] + instancePhase; // phase 0. f= speedCos( instTime1+0 ) + Bias[1]; - driver->setConstant(16+0, maxDeltaPosOS[1]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[0], + maxDeltaPosOS[1]*f); // phase 1. f= speedCos( instTime1+0.25f ) + Bias[1]; - driver->setConstant(16+1, maxDeltaPosOS[1]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[1], + maxDeltaPosOS[1]*f); // phase 2. f= speedCos( instTime1+0.50f ) + Bias[1]; - driver->setConstant(16+2, maxDeltaPosOS[1]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[2], + maxDeltaPosOS[1]*f); // phase 3. f= speedCos( instTime1+0.75f ) + Bias[1]; - driver->setConstant(16+3, maxDeltaPosOS[1]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[3], + maxDeltaPosOS[1]*f); // c[20, 23] take Wind of level 2. @@ -272,29 +360,27 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene float instTime2= _CurrentTime[2] + instancePhase; // phase 0. f= speedCos( instTime2+0 ) + Bias[2]; - driver->setConstant(20+0, maxDeltaPosOS[2]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[0], + maxDeltaPosOS[2]*f); // phase 1. f= speedCos( instTime2+0.25f ) + Bias[2]; - driver->setConstant(20+1, maxDeltaPosOS[2]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[1], + maxDeltaPosOS[2]*f); // phase 2. f= speedCos( instTime2+0.50f ) + Bias[2]; - driver->setConstant(20+2, maxDeltaPosOS[2]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[2], + maxDeltaPosOS[2]*f); // phase 3. f= speedCos( instTime2+0.75f ) + Bias[2]; - driver->setConstant(20+3, maxDeltaPosOS[2]*f); + driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[3], + maxDeltaPosOS[2]*f); } // *************************************************************************** bool CMeshVPWindTree::begin(IDriver *driver, CScene *scene, CMeshBaseInstance *mbi, const NLMISC::CMatrix &invertedModelMat, const NLMISC::CVector & /*viewerPos*/) { - if (!(driver->isVertexProgramSupported() && !driver->isVertexProgramEmulated())) return false; - + if (driver->isVertexProgramEmulated()) return false; - // precompute mesh - setupPerMesh(driver, scene); - - // Setup instance constants - setupPerInstanceConstants(driver, scene, mbi, invertedModelMat); // Activate the good VertexProgram //=============== @@ -302,16 +388,35 @@ bool CMeshVPWindTree::begin(IDriver *driver, CScene *scene, CMeshBaseInstance *m // Get how many pointLights are setuped now. nlassert(scene != NULL); CRenderTrav *renderTrav= &scene->getRenderTrav(); + renderTrav->prepareVPLightSetup(); sint numPls= renderTrav->getNumVPLights()-1; clamp(numPls, 0, CRenderTrav::MaxVPLight-1); + // Enable normalize only if requested by user. Because lighting don't manage correct "scale lighting" uint idVP= (SpecularLighting?2:0) + (driver->isForceNormalize()?1:0) ; // correct VP id for correct unmber of pls. idVP= numPls*4 + idVP; - // activate VP. - driver->activeVertexProgram(_VertexProgram[idVP].get()); + if (driver->activeVertexProgram(_VertexProgram[idVP])) + { + _ActiveVertexProgram = _VertexProgram[idVP]; + } + else + { + // vertex program not supported + _ActiveVertexProgram = NULL; + return false; + } + + + // precompute mesh + setupPerMesh(driver, scene); + + // Setup instance constants + setupPerInstanceConstants(driver, scene, mbi, invertedModelMat); + + return true; @@ -322,6 +427,7 @@ void CMeshVPWindTree::end(IDriver *driver) { // Disable the VertexProgram driver->activeVertexProgram(NULL); + _ActiveVertexProgram = NULL; } // *************************************************************************** @@ -347,7 +453,8 @@ void CMeshVPWindTree::setupLighting(CScene *scene, CMeshBaseInstance *mbi, const nlassert(scene != NULL); CRenderTrav *renderTrav= &scene->getRenderTrav(); // setup cte for lighting - renderTrav->beginVPLightSetup(VPLightConstantStart, SpecularLighting, invertedModelMat); + CVertexProgramWindTree *program = _ActiveVertexProgram; + renderTrav->beginVPLightSetup(program, invertedModelMat); } @@ -367,47 +474,71 @@ bool CMeshVPWindTree::supportMeshBlockRendering() const // *************************************************************************** bool CMeshVPWindTree::isMBRVpOk(IDriver *driver) const { - return driver->isVertexProgramSupported() && !driver->isVertexProgramEmulated(); + initVertexPrograms(); + + if (driver->isVertexProgramEmulated()) + { + return false; + } + for (uint i = 0; i < NumVp; ++i) + { + if (!driver->compileVertexProgram(_VertexProgram[i])) + { + return false; + } + } + return true; } // *************************************************************************** void CMeshVPWindTree::beginMBRMesh(IDriver *driver, CScene *scene) { - // precompute mesh - setupPerMesh(driver, scene); - /* Since need a VertexProgram Activation before activeVBHard, activate a default one bet the common one will be "NoPointLight, NoSpecular, No ForceNormalize" => 0. */ - _LastMBRIdVP= 0; + _LastMBRIdVP = 0; // activate VP. - driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP].get()); + driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP]); + _ActiveVertexProgram = _VertexProgram[_LastMBRIdVP]; + + // precompute mesh + setupPerMesh(driver, scene); + _VertexProgram[_LastMBRIdVP]->PerMeshSetup = true; } // *************************************************************************** void CMeshVPWindTree::beginMBRInstance(IDriver *driver, CScene *scene, CMeshBaseInstance *mbi, const NLMISC::CMatrix &invertedModelMat) { - // setup first constants for this instance - setupPerInstanceConstants(driver, scene, mbi, invertedModelMat); - // Get how many pointLights are setuped now. nlassert(scene != NULL); CRenderTrav *renderTrav= &scene->getRenderTrav(); + renderTrav->prepareVPLightSetup(); sint numPls= renderTrav->getNumVPLights()-1; clamp(numPls, 0, CRenderTrav::MaxVPLight-1); // Enable normalize only if requested by user. Because lighting don't manage correct "scale lighting" - uint idVP= (SpecularLighting?2:0) + (driver->isForceNormalize()?1:0) ; + uint idVP = (SpecularLighting?2:0) + (driver->isForceNormalize()?1:0) ; // correct VP id for correct number of pls. - idVP= numPls*4 + idVP; + idVP = numPls*4 + idVP; // re-activate VP if idVP different from last setup - if( idVP!=_LastMBRIdVP ) + if(idVP != _LastMBRIdVP) { _LastMBRIdVP= idVP; - driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP].get()); + driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP]); + _ActiveVertexProgram = _VertexProgram[_LastMBRIdVP]; + + if (!_VertexProgram[_LastMBRIdVP]->PerMeshSetup) + { + // precompute mesh + setupPerMesh(driver, scene); + _VertexProgram[_LastMBRIdVP]->PerMeshSetup = true; + } } + + // setup first constants for this instance + setupPerInstanceConstants(driver, scene, mbi, invertedModelMat); } // *************************************************************************** @@ -415,6 +546,7 @@ void CMeshVPWindTree::endMBRMesh(IDriver *driver) { // Disable the VertexProgram driver->activeVertexProgram(NULL); + _ActiveVertexProgram = NULL; } // *************************************************************************** diff --git a/code/nel/src/3d/packed_world.cpp b/code/nel/src/3d/packed_world.cpp index 64b669fc4..15d59c724 100644 --- a/code/nel/src/3d/packed_world.cpp +++ b/code/nel/src/3d/packed_world.cpp @@ -152,7 +152,7 @@ void CPackedWorld::getZones(std::vector &zones) void CPackedWorld::serialZoneNames(NLMISC::IStream &f) throw(NLMISC::EStream) { f.serialVersion(1); - f.serialCheck((uint32) 'OWPA'); + f.serialCheck(NELID("OWPA")); f.serialCont(ZoneNames); } diff --git a/code/nel/src/3d/pixel_program.cpp b/code/nel/src/3d/pixel_program.cpp new file mode 100644 index 000000000..adb2163e5 --- /dev/null +++ b/code/nel/src/3d/pixel_program.cpp @@ -0,0 +1,49 @@ +/** \file pixel_program.cpp + * Pixel program definition + */ + +/* Copyright, 2000, 2001 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 "std3d.h" + +#include + +#include + +namespace NL3D +{ + +// *************************************************************************** + +CPixelProgram::CPixelProgram() +{ + +} + +// *************************************************************************** + +CPixelProgram::~CPixelProgram () +{ + +} + +// *************************************************************************** + +} // NL3D diff --git a/code/nel/src/3d/program.cpp b/code/nel/src/3d/program.cpp new file mode 100644 index 000000000..85ba08a6a --- /dev/null +++ b/code/nel/src/3d/program.cpp @@ -0,0 +1,211 @@ +/** + * \file program.cpp + * \brief IProgram + * \date 2013-09-07 15:00GMT + * \author Jan Boon (Kaetemi) + * IProgram + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#include +#include + +// STL includes + +// NeL includes +// #include +#include + +// Project includes +#include + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +// *************************************************************************** + +IProgramDrvInfos::IProgramDrvInfos(IDriver *drv, ItGPUPrgDrvInfoPtrList it) +{ + _Driver = drv; + _DriverIterator = it; +} + +// *************************************************************************** + +IProgramDrvInfos::~IProgramDrvInfos () +{ + _Driver->removeGPUPrgDrvInfoPtr(_DriverIterator); +} + +// *************************************************************************** + +IProgram::IProgram() +{ + +} + +// *************************************************************************** + +IProgram::~IProgram() +{ + // Must kill the drv mirror of this program. + m_DrvInfo.kill(); +} + +const char *CProgramIndex::Names[NUM_UNIFORMS] = +{ + "modelView", + "modelViewInverse", + "modelViewTranspose", + "modelViewInverseTranspose", + + "projection", + "projectionInverse", + "projectionTranspose", + "projectionInverseTranspose", + + "modelViewProjection", + "modelViewProjectionInverse", + "modelViewProjectionTranspose", + "modelViewProjectionInverseTranspose", + + "fog", + + "fogStart", + "fogEnd", + "fogColor", + + "color", + "diffuseColor", + + "constant0", + "constant1", + "constant2", + "constant3", + + "sampler0", + "sampler1", + "sampler2", + "sampler3", + + "texMatrix0", + "texMatrix1", + "texMatrix2", + "texMatrix3", + + "light0DirOrPos", + "light1DirOrPos", + "light2DirOrPos", + "light3DirOrPos", + "light4DirOrPos", + "light5DirOrPos", + "light6DirOrPos", + "light7DirOrPos", + + "light0ColAmb", + "light1ColAmb", + "light2ColAmb", + "light3ColAmb", + "light4ColAmb", + "light5ColAmb", + "light6ColAmb", + "light7ColAmb", + + "light0ColDiff", + "light1ColDiff", + "light2ColDiff", + "light3ColDiff", + "light4ColDiff", + "light5ColDiff", + "light6ColDiff", + "light7ColDiff", + + "light0ColSpec", + "light1ColSpec", + "light2ColSpec", + "light3ColSpec", + "light4ColSpec", + "light5ColSpec", + "light6ColSpec", + "light7ColSpec", + + "light0Shininess", + "light1Shininess", + "light2Shininess", + "light3Shininess", + "light4Shininess", + "light5Shininess", + "light6Shininess", + "light7Shininess", + + "light0ConstAttn", + "light1ConstAttn", + "light2ConstAttn", + "light3ConstAttn", + "light4ConstAttn", + "light5ConstAttn", + "light6ConstAttn", + "light7ConstAttn", + + "light0LinAttn", + "light1LinAttn", + "light2LinAttn", + "light3LinAttn", + "light4LinAttn", + "light5LinAttn", + "light6LinAttn", + "light7LinAttn", + + "light0QuadAttn", + "light1QuadAttn", + "light2QuadAttn", + "light3QuadAttn", + "light4QuadAttn", + "light5QuadAttn", + "light6QuadAttn", + "light7QuadAttn" +}; + +void IProgram::buildInfo(CSource *source) +{ + nlassert(!m_Source); + + m_Source = source; + + // Fill index cache + for (int i = 0; i < CProgramIndex::NUM_UNIFORMS; ++i) + { + m_Index.Indices[i] = getUniformIndex(m_Index.Names[i]); + } + + buildInfo(); +} + +void IProgram::buildInfo() +{ + +} + +} /* namespace NL3D */ + +/* end of file */ diff --git a/code/nel/src/3d/ps_located.cpp b/code/nel/src/3d/ps_located.cpp index f066b6f3c..9be0baf41 100644 --- a/code/nel/src/3d/ps_located.cpp +++ b/code/nel/src/3d/ps_located.cpp @@ -73,7 +73,7 @@ CPSLocated::CPSLocated() : /*_MaxNumFaces(0),*/ _ParametricMotion(false), _TriggerOnDeath(false), _LastForever(true), - _TriggerID((uint32) 'NONE'), + _TriggerID(NELID("NONE")), _NonIntegrableForceNbRefs(0), _NumIntegrableForceWithDifferentBasis(0) { diff --git a/code/nel/src/3d/ps_particle_basic.cpp b/code/nel/src/3d/ps_particle_basic.cpp index 1cb57d2bc..c2d6b6357 100644 --- a/code/nel/src/3d/ps_particle_basic.cpp +++ b/code/nel/src/3d/ps_particle_basic.cpp @@ -786,7 +786,7 @@ void CPSMultiTexturedParticle::setupMaterial(ITexture *primary, IDriver *driver, /// if bump is used, the matrix must be setupped each time (not a material field) if (!_ForceBasicCaps && isMultiTextureEnabled() && _MainOp == EnvBumpMap) { - if (driver->isTextureAddrModeSupported(CMaterial::OffsetTexture)) + if (driver->supportTextureAddrMode(CMaterial::OffsetTexture)) { CTextureBump *tb = dynamic_cast((ITexture *) _Texture2); if (tb != NULL) @@ -858,7 +858,7 @@ void CPSMultiTexturedParticle::setupMaterial(ITexture *primary, IDriver *driver, } else { - if (!_ForceBasicCaps && (driver->isTextureAddrModeSupported(CMaterial::OffsetTexture) || driver->supportEMBM())) // envbumpmap supported ? + if (!_ForceBasicCaps && (driver->supportTextureAddrMode(CMaterial::OffsetTexture) || driver->supportEMBM())) // envbumpmap supported ? { CTextureBump *tb = dynamic_cast((ITexture *) _Texture2); if (tb != NULL) @@ -917,7 +917,7 @@ void CPSMultiTexturedParticle::setupMultiTexEnv(TOperator op, ITexture *tex1, IT mat.enableTexAddrMode(false); break; case EnvBumpMap: - if (drv.isTextureAddrModeSupported(CMaterial::OffsetTexture)) + if (drv.supportTextureAddrMode(CMaterial::OffsetTexture)) { mat.setTexture(0, tex2); mat.setTexture(1, tex1); @@ -1113,7 +1113,7 @@ void CPSMultiTexturedParticle::enumTexs(std::vector NL_PS_FUNC(CPSMultiTexturedParticle_enumTexs) if (_MainOp == EnvBumpMap && !_ForceBasicCaps) { - if (drv.isTextureAddrModeSupported(CMaterial::OffsetTexture) || drv.supportEMBM()) + if (drv.supportTextureAddrMode(CMaterial::OffsetTexture) || drv.supportEMBM()) { if (_Texture2) dest.push_back(_Texture2); } @@ -1132,7 +1132,7 @@ bool CPSMultiTexturedParticle::isAlternateTextureUsed(IDriver &driver) const NL_PS_FUNC(CPSMultiTexturedParticle_isAlternateTextureUsed) if (!isTouched() && areBasicCapsForcedLocal() == areBasicCapsForced()) return (_MultiTexState & AlternateTextureUsed) != 0; if (_MainOp != EnvBumpMap) return false; - return _ForceBasicCaps || (!driver.isTextureAddrModeSupported(CMaterial::OffsetTexture) && !driver.supportEMBM()); + return _ForceBasicCaps || (!driver.supportTextureAddrMode(CMaterial::OffsetTexture) && !driver.supportEMBM()); } } // NL3D diff --git a/code/nel/src/3d/render_trav.cpp b/code/nel/src/3d/render_trav.cpp index 5cf6fd20e..e7dfe89b1 100644 --- a/code/nel/src/3d/render_trav.cpp +++ b/code/nel/src/3d/render_trav.cpp @@ -760,15 +760,24 @@ void CRenderTrav::changeLightSetup(CLightContribution *lightContribution, bool // *************************************************************************** // *************************************************************************** +void CRenderTrav::prepareVPLightSetup() +{ + nlassert(MaxVPLight==4); + _VPNumLights= min(_NumLightEnabled, (uint)MaxVPLight); + // Must force real light setup at least the first time, in changeVPLightSetupMaterial() + _VPMaterialCacheDirty= true; +} // *************************************************************************** -void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const CMatrix &invObjectWM) +void CRenderTrav::beginVPLightSetup(CVertexProgramLighted *program, const CMatrix &invObjectWM) { uint i; - nlassert(MaxVPLight==4); - _VPNumLights= min(_NumLightEnabled, (uint)MaxVPLight); - _VPCurrentCtStart= ctStart; - _VPSupportSpecular= supportSpecular; + // nlassert(MaxVPLight==4); + // _VPNumLights= min(_NumLightEnabled, (uint)MaxVPLight); + // _VPCurrentCtStart= ctStart; + // _VPSupportSpecular= supportSpecular; + _VPCurrent = program; + bool supportSpecular = program->featuresLighted().SupportSpecular; // Prepare Colors (to be multiplied by material) //================ @@ -786,8 +795,11 @@ void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const C // reset other to 0. for(; isetConstant(_VPCurrentCtStart+1+i, 0.f, 0.f, 0.f, 0.f); + _VPLightDiffuse[i] = CRGBA::Black; + if (program->idxLighted().Diffuse[i] != ~0) + { + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Diffuse[i], 0.f, 0.f, 0.f, 0.f); + } } // Specular. _VPCurrentCtStart+5 to 8 (only if supportSpecular) if(supportSpecular) @@ -800,7 +812,10 @@ void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const C for(; isetConstant(_VPCurrentCtStart+5+i, 0.f, 0.f, 0.f, 0.f); + if (program->idxLighted().Specular[i] != ~0) + { + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Specular[i], 0.f, 0.f, 0.f, 0.f); + } } } @@ -816,40 +831,24 @@ void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const C lightDir= invObjectWM.mulVector(_DriverLight[0].getDirection()); lightDir.normalize(); lightDir= -lightDir; - if(supportSpecular) - { - // Setup lightDir. - Driver->setConstant(_VPCurrentCtStart+9, lightDir); - } - else - { - // Setup lightDir. NB: no specular color! - Driver->setConstant(_VPCurrentCtStart+5, lightDir); - } + Driver->setUniform3f(IDriver::VertexProgram, program->idxLighted().DirOrPos[0], lightDir); // The sun is the same for every instance. // Setup PointLights //================ uint startPLPos; - if(supportSpecular) + if (supportSpecular) { // Setup eye in objectSpace for localViewer - Driver->setConstant(_VPCurrentCtStart+11, eye); - // Start at 12. - startPLPos= 12; - } - else - { - // Start at 6. - startPLPos= 6; + Driver->setUniform3f(IDriver::VertexProgram, program->idxLighted().EyePosition, eye); } // For all pointLight enabled (other are black: don't matter) for(i=1; i<_VPNumLights; i++) { // Setup position of light. CVector lightPos; - lightPos= invObjectWM * _DriverLight[i].getPosition(); - Driver->setConstant(_VPCurrentCtStart+startPLPos+(i-1), lightPos); + lightPos = invObjectWM * _DriverLight[i].getPosition(); + Driver->setUniform3f(IDriver::VertexProgram, program->idxLighted().DirOrPos[i], lightPos); } @@ -860,6 +859,9 @@ void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const C // *************************************************************************** void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool excludeStrongest) { + CVertexProgramLighted *program = _VPCurrent; + nlassert(program); + // Must test if at least done one time. if(!_VPMaterialCacheDirty) { @@ -869,7 +871,7 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude _VPMaterialCacheDiffuse == mat.getDiffuse().getPacked() ) { // Same Diffuse part, test if same specular if necessary - if( !_VPSupportSpecular || + if( !program->featuresLighted().SupportSpecular || ( _VPMaterialCacheSpecular == mat.getSpecular().getPacked() && _VPMaterialCacheShininess == mat.getShininess() ) ) { @@ -899,7 +901,7 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude // setup Ambient + Emissive color= _VPFinalAmbient * mat.getAmbient(); color+= mat.getEmissive(); - Driver->setConstant(_VPCurrentCtStart+0, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Ambient, color); // is the strongest light is not excluded, its index should have been setup to _VPNumLights @@ -908,7 +910,7 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude for(i = 0; i < strongestLightIndex; ++i) { color= _VPLightDiffuse[i] * matDiff; - Driver->setConstant(_VPCurrentCtStart+1+i, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Diffuse[i], color); } @@ -917,24 +919,24 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude color= _VPLightDiffuse[i] * matDiff; _StrongestLightDiffuse.set((uint8) (255.f * color.R), (uint8) (255.f * color.G), (uint8) (255.f * color.B), (uint8) (255.f * color.A)); // setup strongest light to black for the gouraud part - Driver->setConstant(_VPCurrentCtStart + 1 + i, 0.f, 0.f, 0.f, 0.f); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Diffuse[i], 0.f, 0.f, 0.f, 0.f); ++i; // setup other lights for(; i < _VPNumLights; i++) { color= _VPLightDiffuse[i] * matDiff; - Driver->setConstant(_VPCurrentCtStart + 1 + i, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Diffuse[i], color); } } // setup Specular - if(_VPSupportSpecular) + if (program->featuresLighted().SupportSpecular) { for(i = 0; i < strongestLightIndex; ++i) { color= _VPLightSpecular[i] * matSpec; color.A= specExp; - Driver->setConstant(_VPCurrentCtStart+5+i, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Specular[i], color); } if (i != _VPNumLights) @@ -943,14 +945,14 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude _StrongestLightSpecular.set((uint8) (255.f * color.R), (uint8) (255.f * color.G), (uint8) (255.f * color.B), (uint8) (255.f * color.A)); // setup strongest light to black (for gouraud part) - Driver->setConstant(_VPCurrentCtStart + 5 + i, 0.f, 0.f, 0.f, 0.f); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Specular[i], 0.f, 0.f, 0.f, 0.f); ++i; // setup other lights for(; i < _VPNumLights; i++) { color= _VPLightSpecular[i] * matSpec; color.A= specExp; - Driver->setConstant(_VPCurrentCtStart + 5 + i, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Specular[i], color); } } } @@ -959,10 +961,7 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude static float alphaCte[4]= {0,0,1,0}; alphaCte[3]= matDiff.A; // setup at good place - if(_VPSupportSpecular) - Driver->setConstant(_VPCurrentCtStart+10, 1, alphaCte); - else - Driver->setConstant(_VPCurrentCtStart+9, 1, alphaCte); + Driver->setUniform4fv(IDriver::VertexProgram, program->idxLighted().DiffuseAlpha, 1, alphaCte); } // *************************************************************************** @@ -1071,9 +1070,9 @@ static const char* LightingVPFragmentSpecular_Begin= \n\ # Compute vertex-to-eye vector normed. \n\ ADD R4, c[CTS+11], -R5; \n\ - DP3 R4.w, R4, R4; \n\ - RSQ R4.w, R4.w; \n\ - MUL R4, R4, R4.w; \n\ + DP3 R1.w, R4, R4; \n\ + RSQ R1.w, R1.w; \n\ + MUL R4, R4, R1.w; \n\ \n\ # Diffuse-Specular Sun \n\ # Compute R1= halfAngleVector= (lightDir+R4).normed(). \n\ @@ -1168,8 +1167,66 @@ static void strReplaceAll(string &strInOut, const string &tokenSrc, const string } } +void CVertexProgramLighted::buildInfo() +{ + CVertexProgram::buildInfo(); + if (profile() == nelvp) + { + // Fixed uniform locations + m_IdxLighted.Ambient = m_FeaturesLighted.CtStartNeLVP + 0; + for (uint i = 0; i < MaxLight; ++i) + { + m_IdxLighted.Diffuse[i] = m_FeaturesLighted.CtStartNeLVP + 1 + i; + } + if (m_FeaturesLighted.SupportSpecular) + { + for (uint i = 0; i < MaxLight; ++i) + { + m_IdxLighted.Specular[i] = m_FeaturesLighted.CtStartNeLVP + 5 + i; + } + m_IdxLighted.DirOrPos[0] = 9; + for (uint i = 1; i < MaxLight; ++i) + { + m_IdxLighted.DirOrPos[i] = m_FeaturesLighted.CtStartNeLVP + (12 - 1) + i; + } + m_IdxLighted.DiffuseAlpha = m_FeaturesLighted.CtStartNeLVP + 10; + m_IdxLighted.EyePosition = m_FeaturesLighted.CtStartNeLVP + 11; + } + else + { + for (uint i = 0; i < MaxLight; ++i) + { + m_IdxLighted.Specular[i] = ~0; + } + for (uint i = 0; i < MaxLight; ++i) + { + m_IdxLighted.DirOrPos[i] = m_FeaturesLighted.CtStartNeLVP + 5 + i; + } + m_IdxLighted.DiffuseAlpha = m_FeaturesLighted.CtStartNeLVP + 9; + m_IdxLighted.EyePosition = ~0; + } + } + else + { + // Named uniform locations + // TODO_VP_GLSL + // m_IdxLighted.Ambient = getUniformIndex("ambient"); + // etc + } + + nlassert(m_IdxLighted.Diffuse[0] != ~0); + if (m_FeaturesLighted.SupportSpecular) + { + nlassert(m_IdxLighted.Specular[0] != ~0); + nlassert(m_IdxLighted.EyePosition != ~0); + } + nlassert(m_IdxLighted.DirOrPos[0] != ~0); + nlassert(m_IdxLighted.DiffuseAlpha != ~0); +} + +// generates the lighting part of a vertex program, nelvp profile // *************************************************************************** -std::string CRenderTrav::getLightVPFragment(uint numActivePointLights, uint ctStart, bool supportSpecular, bool normalize) +std::string CRenderTrav::getLightVPFragmentNeLVP(uint numActivePointLights, uint ctStart, bool supportSpecular, bool normalize) { string ret; diff --git a/code/nel/src/3d/scene.cpp b/code/nel/src/3d/scene.cpp index df5297e2f..fb2d476ac 100644 --- a/code/nel/src/3d/scene.cpp +++ b/code/nel/src/3d/scene.cpp @@ -191,6 +191,8 @@ CScene::CScene(bool bSmallScene) : LightTrav(bSmallScene) _WaterEnvMap = NULL; _GlobalSystemTime= 0.0; + + _RequestParticlesAnimate = false; } // *************************************************************************** void CScene::release() @@ -377,6 +379,13 @@ void CScene::endPartRender() // Reset profiling _NextRenderProfile= false; + IDriver *drv = getDriver(); + drv->activeVertexProgram(NULL); + drv->activePixelProgram(NULL); + drv->activeGeometryProgram(NULL); + + // Ensure nothing animates on subsequent renders + _EllapsedTime = 0.f; /* uint64 total = PSStatsRegisterPSModelObserver + @@ -614,7 +623,11 @@ void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass) // loadBalance LoadBalancingTrav.traverse(); // - _ParticleSystemManager.processAnimate(_EllapsedTime); // deals with permanently animated particle systems + if (_RequestParticlesAnimate) + { + _ParticleSystemManager.processAnimate(_EllapsedTime); // deals with permanently animated particle systems + _RequestParticlesAnimate = false; + } // Light LightTrav.traverse(); } @@ -860,6 +873,9 @@ void CScene::animate( TGlobalAnimationTime atTime ) // Rendered part are invalidate _RenderedPart = UScene::RenderNothing; + + // Particles are animated later due to dependencies + _RequestParticlesAnimate = true; } @@ -1561,6 +1577,8 @@ void CScene::renderOcclusionTestMeshs() nlassert(RenderTrav.getDriver()); RenderTrav.getDriver()->setupViewport(RenderTrav.getViewport()); RenderTrav.getDriver()->activeVertexProgram(NULL); + RenderTrav.getDriver()->activePixelProgram(NULL); + RenderTrav.getDriver()->activeGeometryProgram(NULL); IDriver::TPolygonMode oldPolygonMode = RenderTrav.getDriver()->getPolygonMode(); CMaterial m; m.initUnlit(); diff --git a/code/nel/src/3d/scene_group.cpp b/code/nel/src/3d/scene_group.cpp index 7cfa56b02..d539278cd 100644 --- a/code/nel/src/3d/scene_group.cpp +++ b/code/nel/src/3d/scene_group.cpp @@ -405,7 +405,7 @@ void CInstanceGroup::serial (NLMISC::IStream& f) * ***********************************************/ // Serial a header - f.serialCheck ((uint32)'TPRG'); + f.serialCheck (NELID("TPRG")); /* Version 5: diff --git a/code/nel/src/3d/shader.cpp b/code/nel/src/3d/shader.cpp deleted file mode 100644 index a0d0c3172..000000000 --- a/code/nel/src/3d/shader.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// NeL - MMORPG Framework -// 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 . - -#include "std3d.h" - -#include "nel/3d/shader.h" -#include "nel/3d/driver.h" -#include "nel/misc/path.h" -#include "nel/misc/file.h" - -using namespace std; -using namespace NLMISC; - -namespace NL3D -{ - -// *************************************************************************** - -CShader::~CShader() -{ - // Must kill the drv mirror of this shader. - _DrvInfo.kill(); -} - -// *************************************************************************** - -CShader::CShader() -{ - _ShaderChanged = true; -} - -// *************************************************************************** - -void CShader::setText (const char *text) -{ - _Text = text; - _ShaderChanged = true; -} - -// *************************************************************************** - -void CShader::setName (const char *name) -{ - _Name = name; - _ShaderChanged = true; -} - -// *************************************************************************** - -bool CShader::loadShaderFile (const char *filename) -{ - _Text = ""; - // Lookup - string _filename = CPath::lookup(filename, false, true, true); - if (!_filename.empty()) - { - // File length - uint size = CFile::getFileSize (_filename); - _Text.reserve (size+1); - - try - { - CIFile file; - if (file.open (_filename)) - { - // Read it - while (!file.eof ()) - { - char line[512]; - file.getline (line, 512); - _Text += line; - } - - // Set the shader name - _Name = CFile::getFilename (filename); - return true; - } - else - { - nlwarning ("Can't open the file %s for reading", _filename.c_str()); - } - } - catch (const Exception &e) - { - nlwarning ("Error while reading %s : %s", _filename.c_str(), e.what()); - } - } - return false; -} - -// *************************************************************************** - -IShaderDrvInfos::~IShaderDrvInfos() -{ - _Driver->removeShaderDrvInfoPtr(_DriverIterator); -} - -} // NL3D diff --git a/code/nel/src/3d/shadow_map_manager.cpp b/code/nel/src/3d/shadow_map_manager.cpp index 79f4ade20..383a28184 100644 --- a/code/nel/src/3d/shadow_map_manager.cpp +++ b/code/nel/src/3d/shadow_map_manager.cpp @@ -244,11 +244,12 @@ void CShadowMapManager::addShadowReceiver(CTransform *model) void CShadowMapManager::renderGenerate(CScene *scene) { H_AUTO( NL3D_ShadowManager_Generate ); - + // Each frame, do a small garbage collector for unused free textures. garbageShadowTextures(scene); IDriver *driverForShadowGeneration= scene->getRenderTrav().getAuxDriver(); + CSmartPtr previousRenderTarget = driverForShadowGeneration->getRenderTarget(); // Init // ******** @@ -488,7 +489,7 @@ void CShadowMapManager::renderGenerate(CScene *scene) } // Set default render target - driverForShadowGeneration->setRenderTarget (NULL); + driverForShadowGeneration->setRenderTarget (previousRenderTarget); // Allow Writing on all. driverForShadowGeneration->setColorMask(true, true, true, true); diff --git a/code/nel/src/3d/shape.cpp b/code/nel/src/3d/shape.cpp index adc610827..cf61185cd 100644 --- a/code/nel/src/3d/shape.cpp +++ b/code/nel/src/3d/shape.cpp @@ -116,7 +116,7 @@ IShape* CShapeStream::getShapePointer () const void CShapeStream::serial(NLMISC::IStream &f) throw(NLMISC::EStream) { // First, serial an header or checking if it is correct - f.serialCheck ((uint32)'PAHS'); + f.serialCheck (NELID("PAHS")); // Then, serial the shape f.serialPolyPtr (_Shape); diff --git a/code/nel/src/3d/skeleton_weight.cpp b/code/nel/src/3d/skeleton_weight.cpp index 4668a005a..ba037236a 100644 --- a/code/nel/src/3d/skeleton_weight.cpp +++ b/code/nel/src/3d/skeleton_weight.cpp @@ -60,7 +60,7 @@ void CSkeletonWeight::build (const TNodeArray& array) void CSkeletonWeight::serial (NLMISC::IStream& f) { // Serial a header - f.serialCheck ((uint32)'TWKS'); + f.serialCheck (NELID("TWKS")); // Serial a version number (void)f.serialVersion (0); diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp new file mode 100644 index 000000000..c5c5e262a --- /dev/null +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -0,0 +1,463 @@ +/** + * \file stereo_debugger.cpp + * \brief CStereoDebugger + * \date 2013-07-03 20:17GMT + * \author Jan Boon (Kaetemi) + * CStereoDebugger + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#if !FINAL_VERSION +#include +#include + +// STL includes + +// NeL includes +// #include + +// Project includes +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +namespace { + +const char *a_arbfp1 = + "!!ARBfp1.0\n" + "PARAM c[1] = { { 1, 0, 0.5 } };\n" + "TEMP R0;\n" + "TEMP R1;\n" + "TEMP R2;\n" + "TEX R0, fragment.texcoord[0], texture[0], 2D;\n" + "TEX R1, fragment.texcoord[0], texture[1], 2D;\n" + "ADD R2, R0, -R1;\n" + "ADD R1, R0, R1;\n" + "MUL R1, R1, c[0].z;\n" + "ABS R2, R2;\n" + "CMP R2, -R2, c[0].x, c[0].y;\n" + "ADD_SAT R2.x, R2, R2.y;\n" + "ADD_SAT R2.x, R2, R2.z;\n" + "ADD_SAT R2.x, R2, R2.w;\n" + "ABS R2.x, R2;\n" + "CMP R2.x, -R2, c[0].y, c[0];\n" + "ABS R0.x, R2;\n" + "CMP R2.x, -R0, c[0].y, c[0];\n" + "MOV R0.xzw, R1;\n" + "MAD R0.y, R1, c[0].z, c[0].z;\n" + "CMP R0, -R2.x, R1, R0;\n" + "MAD R1.x, R0, c[0].z, c[0].z;\n" + "CMP result.color.x, -R2, R1, R0;\n" + "MOV result.color.yzw, R0;\n" + "END\n"; + +const char *a_ps_2_0 = + "ps_2_0\n" + // cgc version 3.1.0013, build date Apr 18 2012 + // command line args: -profile ps_2_0 + // source file: pp_stereo_debug.cg + //vendor NVIDIA Corporation + //version 3.1.0.13 + //profile ps_2_0 + //program pp_stereo_debug + //semantic pp_stereo_debug.cTex0 : TEX0 + //semantic pp_stereo_debug.cTex1 : TEX1 + //var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //var sampler2D cTex0 : TEX0 : texunit 0 : 1 : 1 + //var sampler2D cTex1 : TEX1 : texunit 1 : 2 : 1 + //var float4 oCol : $vout.COLOR : COL : 3 : 1 + //const c[0] = 0 1 0.5 + "dcl_2d s0\n" + "dcl_2d s1\n" + "def c0, 0.00000000, 1.00000000, 0.50000000, 0\n" + "dcl t0.xy\n" + "texld r1, t0, s1\n" + "texld r2, t0, s0\n" + "add r0, r2, -r1\n" + "add r1, r2, r1\n" + "mul r1, r1, c0.z\n" + "abs r0, r0\n" + "cmp r0, -r0, c0.x, c0.y\n" + "add_pp_sat r0.x, r0, r0.y\n" + "add_pp_sat r0.x, r0, r0.z\n" + "add_pp_sat r0.x, r0, r0.w\n" + "abs_pp r0.x, r0\n" + "cmp_pp r0.x, -r0, c0.y, c0\n" + "abs_pp r0.x, r0\n" + "mov r2.xzw, r1\n" + "mad r2.y, r1, c0.z, c0.z\n" + "cmp r2, -r0.x, r1, r2\n" + "mad r1.x, r2, c0.z, c0.z\n" + "mov r0.yzw, r2\n" + "cmp r0.x, -r0, r1, r2\n" + "mov oC0, r0\n"; + +class CStereoDebuggerFactory : public IStereoDeviceFactory +{ +public: + IStereoDisplay *createDevice() const + { + return new CStereoDebugger(); + } +}; + +} /* anonymous namespace */ + +CStereoDebugger::CStereoDebugger() : m_Driver(NULL), m_Stage(0), m_SubStage(0), m_LeftTexU(NULL), m_RightTexU(NULL), m_PixelProgram(NULL) +{ + +} + +CStereoDebugger::~CStereoDebugger() +{ + releaseTextures(); + + if (!m_Mat.empty()) + { + m_Driver->deleteMaterial(m_Mat); + } + + delete m_PixelProgram; + m_PixelProgram = NULL; + + m_Driver = NULL; +} + +/// Sets driver and generates necessary render targets +void CStereoDebugger::setDriver(NL3D::UDriver *driver) +{ + nlassert(!m_PixelProgram); + + m_Driver = driver; + NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + + if (drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + { + m_PixelProgram = new CPixelProgram(); + // arbfp1 + { + IProgram::CSource *source = new IProgram::CSource(); + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->Profile = IProgram::arbfp1; + source->setSourcePtr(a_arbfp1); + m_PixelProgram->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_PixelProgram->addSource(source); + } + if (!drvInternal->compilePixelProgram(m_PixelProgram)) + { + nlwarning("No supported pixel program for stereo debugger"); + + delete m_PixelProgram; + m_PixelProgram = NULL; + } + } + + if (m_PixelProgram) + { + initTextures(); + + m_Mat = m_Driver->createMaterial(); + m_Mat.initUnlit(); + m_Mat.setColor(CRGBA::White); + m_Mat.setBlend (false); + m_Mat.setAlphaTest (false); + NL3D::CMaterial *mat = m_Mat.getObjectPtr(); + mat->setShader(NL3D::CMaterial::Normal); + mat->setBlendFunc(CMaterial::one, CMaterial::zero); + mat->setZWrite(false); + mat->setZFunc(CMaterial::always); + mat->setDoubleSided(true); + + setTextures(); + + m_QuadUV.V0 = CVector(0.f, 0.f, 0.5f); + m_QuadUV.V1 = CVector(1.f, 0.f, 0.5f); + m_QuadUV.V2 = CVector(1.f, 1.f, 0.5f); + m_QuadUV.V3 = CVector(0.f, 1.f, 0.5f); + + m_QuadUV.Uv0 = CUV(0.f, 0.f); + m_QuadUV.Uv1 = CUV(1.f, 0.f); + m_QuadUV.Uv2 = CUV(1.f, 1.f); + m_QuadUV.Uv3 = CUV(0.f, 1.f); + } +} + +void CStereoDebugger::releaseTextures() +{ + if (!m_Mat.empty()) + { + m_Mat.getObjectPtr()->setTexture(0, NULL); + m_Mat.getObjectPtr()->setTexture(1, NULL); + m_Driver->deleteMaterial(m_Mat); + } + + delete m_LeftTexU; + m_LeftTexU = NULL; + m_LeftTex = NULL; // CSmartPtr + + delete m_RightTexU; + m_RightTexU = NULL; + m_RightTex = NULL; // CSmartPtr +} + +void CStereoDebugger::initTextures() +{ + uint32 width, height; + m_Driver->getWindowSize(width, height); + NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); + + m_LeftTex = new CTextureBloom(); + m_LeftTex->setRenderTarget(true); + m_LeftTex->setReleasable(false); + m_LeftTex->resize(width, height); + m_LeftTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_LeftTex->setWrapS(ITexture::Clamp); + m_LeftTex->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*m_LeftTex); + m_LeftTexU = new CTextureUser(m_LeftTex); + nlassert(!drvInternal->isTextureRectangle(m_LeftTex)); // not allowed + + m_RightTex = new CTextureBloom(); + m_RightTex->setRenderTarget(true); + m_RightTex->setReleasable(false); + m_RightTex->resize(width, height); + m_RightTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_RightTex->setWrapS(ITexture::Clamp); + m_RightTex->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*m_RightTex); + m_RightTexU = new CTextureUser(m_RightTex); + nlassert(!drvInternal->isTextureRectangle(m_RightTex)); // not allowed +} + +void CStereoDebugger::setTextures() +{ + NL3D::CMaterial *mat = m_Mat.getObjectPtr(); + mat->setTexture(0, m_LeftTex); + mat->setTexture(1, m_RightTex); +} + +void CStereoDebugger::verifyTextures() +{ + if (m_Driver) + { + uint32 width, height; + m_Driver->getWindowSize(width, height); + if (m_LeftTex->getWidth() != width + || m_RightTex->getWidth() != width + || m_LeftTex->getHeight() != height + || m_RightTex->getHeight() != height) + { + nldebug("Rebuild textures"); + releaseTextures(); + initTextures(); + setTextures(); + } + } +} + +/// Gets the required screen resolution for this device +bool CStereoDebugger::getScreenResolution(uint &width, uint &height) +{ + return false; +} + +/// Set latest camera position etcetera +void CStereoDebugger::updateCamera(uint cid, const NL3D::UCamera *camera) +{ + m_Frustum[cid] = camera->getFrustum(); +} + +/// Get the frustum to use for clipping +void CStereoDebugger::getClippingFrustum(uint cid, NL3D::UCamera *camera) const +{ + // do nothing +} + +/// Is there a next pass +bool CStereoDebugger::nextPass() +{ + if (m_Driver->getPolygonMode() == UDriver::Filled) + { + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + return true; + case 1: + ++m_Stage; + m_SubStage = 0; + return true; + case 2: + ++m_Stage; + m_SubStage = 0; + return true; + case 3: + m_Stage = 0; + m_SubStage = 0; + return false; + } + } + else + { + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + return true; + case 1: + m_Stage = 0; + m_SubStage = 0; + return false; + } + } + return false; +} + +/// Gets the current viewport +const NL3D::CViewport &CStereoDebugger::getCurrentViewport() const +{ + if (m_Stage % 2) return m_LeftViewport; + else return m_RightViewport; +} + +/// Gets the current camera frustum +const NL3D::CFrustum &CStereoDebugger::getCurrentFrustum(uint cid) const +{ + return m_Frustum[cid]; +} + +/// Gets the current camera frustum +void CStereoDebugger::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const +{ + // do nothing +} + +/// Gets the current camera matrix +void CStereoDebugger::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const +{ + // do nothing +} + +/// At the start of a new render target +bool CStereoDebugger::wantClear() +{ + m_SubStage = 1; + return m_Stage != 3; +} + +/// The 3D scene +bool CStereoDebugger::wantScene() +{ + m_SubStage = 2; + return m_Stage != 3; +} + +/// Interface within the 3D scene +bool CStereoDebugger::wantInterface3D() +{ + m_SubStage = 3; + return m_Stage == 3; +} + +/// 2D Interface +bool CStereoDebugger::wantInterface2D() +{ + m_SubStage = 4; + return m_Stage == 3; +} + +/// Returns true if a new render target was set, always fase if not using render targets +bool CStereoDebugger::beginRenderTarget() +{ + if (m_Stage != 3 && m_Driver && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + if (m_Stage % 2) static_cast(m_Driver)->setRenderTarget(*m_RightTexU, 0, 0, 0, 0); + else static_cast(m_Driver)->setRenderTarget(*m_LeftTexU, 0, 0, 0, 0); + return true; + } + return false; +} + +/// Returns true if a render target was fully drawn, always false if not using render targets +bool CStereoDebugger::endRenderTarget() +{ + if (m_Stage != 3 && m_Driver && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + CTextureUser cu; + (static_cast(m_Driver))->setRenderTarget(cu); + bool fogEnabled = m_Driver->fogEnabled(); + m_Driver->enableFog(false); + + m_Driver->setMatrixMode2D11(); + CViewport vp = CViewport(); + m_Driver->setViewport(vp); + uint32 width, height; + NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); + NL3D::CMaterial *mat = m_Mat.getObjectPtr(); + mat->setTexture(0, m_LeftTex); + mat->setTexture(1, m_RightTex); + drvInternal->activePixelProgram(m_PixelProgram); + + m_Driver->drawQuad(m_QuadUV, m_Mat); + + drvInternal->activePixelProgram(NULL); + m_Driver->enableFog(fogEnabled); + + return true; + } + return false; +} + +void CStereoDebugger::listDevices(std::vector &devicesOut) +{ + CStereoDeviceInfo devInfo; + devInfo.Factory = new CStereoDebuggerFactory(); + devInfo.Library = CStereoDeviceInfo::NeL3D; + devInfo.Class = CStereoDeviceInfo::StereoDisplay; + devInfo.Manufacturer = "NeL"; + devInfo.ProductName = "Stereo Debugger"; + devInfo.Serial = "NL-3D-DEBUG"; + devicesOut.push_back(devInfo); +} + +} /* namespace NL3D */ + +#endif /* #if !FINAL_VERSION */ + +/* end of file */ diff --git a/code/nel/src/3d/stereo_display.cpp b/code/nel/src/3d/stereo_display.cpp new file mode 100644 index 000000000..eace867fc --- /dev/null +++ b/code/nel/src/3d/stereo_display.cpp @@ -0,0 +1,112 @@ +/** + * \file stereo_display.cpp + * \brief IStereoDisplay + * \date 2013-06-27 16:29GMT + * \author Jan Boon (Kaetemi) + * IStereoDisplay + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#include +#include + +// STL includes + +// NeL includes +// #include + +// Project includes +#include +#include +#include + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +IStereoDisplay::IStereoDisplay() +{ + +} + +IStereoDisplay::~IStereoDisplay() +{ + +} + +const char *IStereoDisplay::getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library) +{ + static const char *nel3dName = "NeL 3D"; + static const char *ovrName = "Oculus SDK"; + static const char *libvrName = "LibVR"; + static const char *openhmdName = "OpenHMD"; + switch (library) + { + case CStereoDeviceInfo::NeL3D: + return nel3dName; + case CStereoDeviceInfo::OVR: + return ovrName; + case CStereoDeviceInfo::LibVR: + return libvrName; + case CStereoDeviceInfo::OpenHMD: + return openhmdName; + } + nlerror("Invalid device library specified"); + return ""; +} + +void IStereoDisplay::listDevices(std::vector &devicesOut) +{ +#ifdef HAVE_LIBOVR + CStereoOVR::listDevices(devicesOut); +#endif +#ifdef HAVE_LIBVR + CStereoLibVR::listDevices(devicesOut); +#endif +#if !FINAL_VERSION + CStereoDebugger::listDevices(devicesOut); +#endif +} + +IStereoDisplay *IStereoDisplay::createDevice(const CStereoDeviceInfo &deviceInfo) +{ + return deviceInfo.Factory->createDevice(); +} + +void IStereoDisplay::releaseUnusedLibraries() +{ +#ifdef HAVE_LIBOVR + if (!CStereoOVR::isLibraryInUse()) + CStereoOVR::releaseLibrary(); +#endif +} + +void IStereoDisplay::releaseAllLibraries() +{ +#ifdef HAVE_LIBOVR + CStereoOVR::releaseLibrary(); +#endif +} + +} /* namespace NL3D */ + +/* end of file */ diff --git a/code/nel/src/3d/stereo_hmd.cpp b/code/nel/src/3d/stereo_hmd.cpp new file mode 100644 index 000000000..d28017482 --- /dev/null +++ b/code/nel/src/3d/stereo_hmd.cpp @@ -0,0 +1,55 @@ +/** + * \file stereo_hmd.cpp + * \brief IStereoHMD + * \date 2013-06-27 16:30GMT + * \author Jan Boon (Kaetemi) + * IStereoHMD + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#include +#include + +// STL includes + +// NeL includes +// #include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +IStereoHMD::IStereoHMD() +{ + +} + +IStereoHMD::~IStereoHMD() +{ + +} + +} /* namespace NL3D */ + +/* end of file */ diff --git a/code/nel/src/3d/stereo_libvr.cpp b/code/nel/src/3d/stereo_libvr.cpp new file mode 100644 index 000000000..8ce64e07c --- /dev/null +++ b/code/nel/src/3d/stereo_libvr.cpp @@ -0,0 +1,642 @@ +/** + * \file stereo_libvr.cpp + * \brief CStereoLibVR + * \date 2013-08-19 19:17MT + * \author Thibaut Girka (ThibG) + * CStereoLibVR + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + */ + +#ifdef HAVE_LIBVR + +#include +#include +#include + +// STL includes +#include + +// External includes +extern "C" { +#include +} + +// NeL includes +// #include +#include +#include +#include +#include +#include +#include +#include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +extern const char *g_StereoOVR_fp40; //TODO: what? +extern const char *g_StereoOVR_arbfp1; //TODO: what? +extern const char *g_StereoOVR_ps_2_0; //TODO: what? + +namespace { +sint s_DeviceCounter = 0; +}; + +class CStereoLibVRDeviceHandle : public IStereoDeviceFactory +{ +public: + // fixme: virtual destructor??? + IStereoDisplay *createDevice() const + { + CStereoLibVR *stereo = new CStereoLibVR(this); + if (stereo->isDeviceCreated()) + return stereo; + delete stereo; + return NULL; + } +}; + +class CStereoLibVRDevicePtr +{ +public: + struct hmd *HMDDevice; + struct display_info HMDInfo; + float InterpupillaryDistance; +}; + +CStereoLibVR::CStereoLibVR(const CStereoLibVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL), m_PixelProgram(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) +{ + struct stereo_config st_conf; + + ++s_DeviceCounter; + // For now, LibVR doesn't support multiple devices... + m_DevicePtr = new CStereoLibVRDevicePtr(); + m_DevicePtr->HMDDevice = hmd_open_first(0); + m_DevicePtr->InterpupillaryDistance = 0.0647; //TODO + + if (m_DevicePtr->HMDDevice) + { + hmd_get_display_info(m_DevicePtr->HMDDevice, &m_DevicePtr->HMDInfo); + hmd_get_stereo_config(m_DevicePtr->HMDDevice, &st_conf); + nldebug("LibVR: HScreenSize: %f, VScreenSize: %f", m_DevicePtr->HMDInfo.h_screen_size, m_DevicePtr->HMDInfo.v_screen_size); + nldebug("LibVR: VScreenCenter: %f", m_DevicePtr->HMDInfo.v_center); + nldebug("LibVR: EyeToScreenDistance: %f", m_DevicePtr->HMDInfo.eye_to_screen[0]); + nldebug("LibVR: LensSeparationDistance: %f", m_DevicePtr->HMDInfo.lens_separation); + nldebug("LibVR: HResolution: %i, VResolution: %i", m_DevicePtr->HMDInfo.h_resolution, m_DevicePtr->HMDInfo.v_resolution); + nldebug("LibVR: DistortionK[0]: %f, DistortionK[1]: %f", m_DevicePtr->HMDInfo.distortion_k[0], m_DevicePtr->HMDInfo.distortion_k[1]); + nldebug("LibVR: DistortionK[2]: %f, DistortionK[3]: %f", m_DevicePtr->HMDInfo.distortion_k[2], m_DevicePtr->HMDInfo.distortion_k[3]); + nldebug("LibVR: Scale: %f", st_conf.distort.scale); + m_LeftViewport.init(0.f, 0.f, 0.5f, 1.0f); + m_RightViewport.init(0.5f, 0.f, 0.5f, 1.0f); + } +} + +CStereoLibVR::~CStereoLibVR() +{ + if (!m_BarrelMat.empty()) + { + m_BarrelMat.getObjectPtr()->setTexture(0, NULL); + m_Driver->deleteMaterial(m_BarrelMat); + } + delete m_BarrelTexU; + m_BarrelTexU = NULL; + m_BarrelTex = NULL; // CSmartPtr + + delete m_PixelProgram; + m_PixelProgram = NULL; + + m_Driver = NULL; + + if (m_DevicePtr->HMDDevice) + hmd_close(m_DevicePtr->HMDDevice); + + delete m_DevicePtr; + m_DevicePtr = NULL; + + --s_DeviceCounter; +} + +void CStereoLibVR::setDriver(NL3D::UDriver *driver) +{ + nlassert(!m_PixelProgram); + + NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + { + nldebug("VR: fp40"); + m_PixelProgram = new CPixelProgram(g_StereoOVR_fp40); + } + else if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + { + nldebug("VR: arbfp1"); + m_PixelProgram = new CPixelProgram(g_StereoOVR_arbfp1); + } + else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) + { + nldebug("VR: ps_2_0"); + m_PixelProgram = new CPixelProgram(g_StereoOVR_ps_2_0); + } + + if (m_PixelProgram) + { + m_Driver = driver; + + m_BarrelTex = new CTextureBloom(); // lol bloom + m_BarrelTex->setRenderTarget(true); + m_BarrelTex->setReleasable(false); + m_BarrelTex->resize(m_DevicePtr->HMDInfo.h_resolution, m_DevicePtr->HMDInfo.v_resolution); + m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_BarrelTex->setWrapS(ITexture::Clamp); + m_BarrelTex->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*m_BarrelTex); + m_BarrelTexU = new CTextureUser(m_BarrelTex); + + m_BarrelMat = m_Driver->createMaterial(); + m_BarrelMat.initUnlit(); + m_BarrelMat.setColor(CRGBA::White); + m_BarrelMat.setBlend (false); + m_BarrelMat.setAlphaTest (false); + NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); + barrelMat->setShader(NL3D::CMaterial::PostProcessing); + barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero); + barrelMat->setZWrite(false); + barrelMat->setZFunc(CMaterial::always); + barrelMat->setDoubleSided(true); + barrelMat->setTexture(0, m_BarrelTex); + + m_BarrelQuadLeft.V0 = CVector(0.f, 0.f, 0.5f); + m_BarrelQuadLeft.V1 = CVector(0.5f, 0.f, 0.5f); + m_BarrelQuadLeft.V2 = CVector(0.5f, 1.f, 0.5f); + m_BarrelQuadLeft.V3 = CVector(0.f, 1.f, 0.5f); + + m_BarrelQuadRight.V0 = CVector(0.5f, 0.f, 0.5f); + m_BarrelQuadRight.V1 = CVector(1.f, 0.f, 0.5f); + m_BarrelQuadRight.V2 = CVector(1.f, 1.f, 0.5f); + m_BarrelQuadRight.V3 = CVector(0.5f, 1.f, 0.5f); + + nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // not allowed + + m_BarrelQuadLeft.Uv0 = CUV(0.f, 0.f); + m_BarrelQuadLeft.Uv1 = CUV(0.5f, 0.f); + m_BarrelQuadLeft.Uv2 = CUV(0.5f, 1.f); + m_BarrelQuadLeft.Uv3 = CUV(0.f, 1.f); + + m_BarrelQuadRight.Uv0 = CUV(0.5f, 0.f); + m_BarrelQuadRight.Uv1 = CUV(1.f, 0.f); + m_BarrelQuadRight.Uv2 = CUV(1.f, 1.f); + m_BarrelQuadRight.Uv3 = CUV(0.5f, 1.f); + } + else + { + nlwarning("VR: No pixel program support"); + } +} + +bool CStereoLibVR::getScreenResolution(uint &width, uint &height) +{ + width = m_DevicePtr->HMDInfo.h_resolution; + height = m_DevicePtr->HMDInfo.v_resolution; + return true; +} + +void CStereoLibVR::initCamera(uint cid, const NL3D::UCamera *camera) +{ + struct stereo_config st_conf; + hmd_get_stereo_config(m_DevicePtr->HMDDevice, &st_conf); + + float ar = st_conf.proj.aspect_ratio; + float fov = st_conf.proj.yfov; + m_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); + m_RightFrustum[cid] = m_LeftFrustum[cid]; + + float projectionCenterOffset = st_conf.proj.projection_offset * 0.5 * (m_LeftFrustum[cid].Right - m_LeftFrustum[cid].Left); + nldebug("LibVR: projectionCenterOffset = %f", projectionCenterOffset); + + m_LeftFrustum[cid].Left -= projectionCenterOffset; + m_LeftFrustum[cid].Right -= projectionCenterOffset; + m_RightFrustum[cid].Left += projectionCenterOffset; + m_RightFrustum[cid].Right += projectionCenterOffset; + + // TODO: Clipping frustum should also take into account the IPD + m_ClippingFrustum[cid] = m_LeftFrustum[cid]; + m_ClippingFrustum[cid].Left = min(m_LeftFrustum[cid].Left, m_RightFrustum[cid].Left); + m_ClippingFrustum[cid].Right = max(m_LeftFrustum[cid].Right, m_RightFrustum[cid].Right); +} + +/// Get the frustum to use for clipping +void CStereoLibVR::getClippingFrustum(uint cid, NL3D::UCamera *camera) const +{ + camera->setFrustum(m_ClippingFrustum[cid]); +} + +void CStereoLibVR::updateCamera(uint cid, const NL3D::UCamera *camera) +{ + if (camera->getFrustum().Near != m_LeftFrustum[cid].Near + || camera->getFrustum().Far != m_LeftFrustum[cid].Far) + CStereoLibVR::initCamera(cid, camera); + m_CameraMatrix[cid] = camera->getMatrix(); +} + +bool CStereoLibVR::nextPass() +{ + // Do not allow weird stuff. + uint32 width, height; + m_Driver->getWindowSize(width, height); + nlassert(width == m_DevicePtr->HMDInfo.h_resolution); + nlassert(height == m_DevicePtr->HMDInfo.v_resolution); + + if (m_Driver->getPolygonMode() == UDriver::Filled) + { + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + // stage 1: + // (initBloom) + // clear buffer + // draw scene left + return true; + case 1: + ++m_Stage; + m_SubStage = 0; + // stage 2: + // draw scene right + return true; + case 2: + ++m_Stage; + m_SubStage = 0; + // stage 3: + // (endBloom) + // draw interface 3d left + return true; + case 3: + ++m_Stage; + m_SubStage = 0; + // stage 4: + // draw interface 3d right + return true; + case 4: + ++m_Stage; + m_SubStage = 0; + // stage 5: + // (endInterfacesDisplayBloom) + // draw interface 2d left + return true; + case 5: + ++m_Stage; + m_SubStage = 0; + // stage 6: + // draw interface 2d right + return true; + case 6: + m_Stage = 0; + m_SubStage = 0; + // present + m_OrientationCached = false; + return false; + } + } + else + { + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + return true; + case 1: + m_Stage = 0; + m_SubStage = 0; + return false; + } + } + nlerror("Invalid stage"); + m_Stage = 0; + m_SubStage = 0; + m_OrientationCached = false; + return false; +} + +const NL3D::CViewport &CStereoLibVR::getCurrentViewport() const +{ + if (m_Stage % 2) return m_LeftViewport; + else return m_RightViewport; +} + +const NL3D::CFrustum &CStereoLibVR::getCurrentFrustum(uint cid) const +{ + if (m_Stage % 2) return m_LeftFrustum[cid]; + else return m_RightFrustum[cid]; +} + +void CStereoLibVR::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const +{ + if (m_Stage % 2) camera->setFrustum(m_LeftFrustum[cid]); + else camera->setFrustum(m_RightFrustum[cid]); +} + +void CStereoLibVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const +{ + CMatrix translate; + if (m_Stage % 2) translate.translate(CVector((m_DevicePtr->InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f)); + else translate.translate(CVector((m_DevicePtr->InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f)); + CMatrix mat = m_CameraMatrix[cid] * translate; + if (camera->getTransformMode() == NL3D::UTransformable::RotQuat) + { + camera->setPos(mat.getPos()); + camera->setRotQuat(mat.getRot()); + } + else + { + // camera->setTransformMode(NL3D::UTransformable::DirectMatrix); + camera->setMatrix(mat); + } +} + +bool CStereoLibVR::wantClear() +{ + switch (m_Stage) + { + case 1: + m_SubStage = 1; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoLibVR::wantScene() +{ + switch (m_Stage) + { + case 1: + case 2: + m_SubStage = 2; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoLibVR::wantInterface3D() +{ + switch (m_Stage) + { + case 3: + case 4: + m_SubStage = 3; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoLibVR::wantInterface2D() +{ + switch (m_Stage) + { + case 5: + case 6: + m_SubStage = 4; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + + +/// Returns non-NULL if a new render target was set +bool CStereoLibVR::beginRenderTarget() +{ + // render target always set before driver clear + // nlassert(m_SubStage <= 1); + if (m_Driver && m_Stage == 1 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + static_cast(m_Driver)->setRenderTarget(*m_BarrelTexU, 0, 0, 0, 0); + return true; + } + return false; +} + +/// Returns true if a render target was fully drawn +bool CStereoLibVR::endRenderTarget() +{ + // after rendering of course + // nlassert(m_SubStage > 1); + if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui + { + struct stereo_config st_conf; + hmd_get_stereo_config(m_DevicePtr->HMDDevice, &st_conf); + CTextureUser cu; + (static_cast(m_Driver))->setRenderTarget(cu); + bool fogEnabled = m_Driver->fogEnabled(); + m_Driver->enableFog(false); + + m_Driver->setMatrixMode2D11(); + CViewport vp = CViewport(); + m_Driver->setViewport(vp); + uint32 width, height; + m_Driver->getWindowSize(width, height); + NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); + NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); + barrelMat->setTexture(0, m_BarrelTex); + drvInternal->activePixelProgram(m_PixelProgram); + + float w = float(m_BarrelQuadLeft.V1.x),// / float(width), + h = float(m_BarrelQuadLeft.V2.y),// / float(height), + x = float(m_BarrelQuadLeft.V0.x),/// / float(width), + y = float(m_BarrelQuadLeft.V0.y);// / float(height); + + //TODO: stereo_config stuff + float lensViewportShift = st_conf.proj.projection_offset; + + float lensCenterX = x + (w + lensViewportShift * 0.5f) * 0.5f; + float lensCenterY = y + h * 0.5f; + float screenCenterX = x + w * 0.5f; + float screenCenterY = y + h * 0.5f; + float scaleX = (w / 2 / st_conf.distort.scale); + float scaleY = (h / 2 / st_conf.distort.scale); + float scaleInX = (2 / w); + float scaleInY = (2 / h); + drvInternal->setPixelProgramConstant(0, lensCenterX, lensCenterY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(1, screenCenterX, screenCenterY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(2, scaleX, scaleY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(3, scaleInX, scaleInY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(4, 1, st_conf.distort.distortion_k); + + + m_Driver->drawQuad(m_BarrelQuadLeft, m_BarrelMat); + + x = w; + lensCenterX = x + (w - lensViewportShift * 0.5f) * 0.5f; + screenCenterX = x + w * 0.5f; + drvInternal->setPixelProgramConstant(0, lensCenterX, lensCenterY, 0.f, 0.f); + drvInternal->setPixelProgramConstant(1, screenCenterX, screenCenterY, 0.f, 0.f); + + m_Driver->drawQuad(m_BarrelQuadRight, m_BarrelMat); + + drvInternal->activePixelProgram(NULL); + m_Driver->enableFog(fogEnabled); + + return true; + } + return false; +} + +NLMISC::CQuat CStereoLibVR::getOrientation() const +{ + if (m_OrientationCached) + return m_OrientationCache; + + unsigned int t = NLMISC::CTime::getLocalTime(); + hmd_update(m_DevicePtr->HMDDevice, &t); + + float quat[4]; + hmd_get_rotation(m_DevicePtr->HMDDevice, quat); + NLMISC::CMatrix coordsys; + float csys[] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + coordsys.set(csys); + NLMISC::CMatrix matovr; + matovr.setRot(NLMISC::CQuat(quat[1], quat[2], quat[3], quat[0])); + NLMISC::CMatrix matr; + matr.rotateX(NLMISC::Pi * 0.5f); // fix this properly... :) (note: removing this allows you to use rift while lying down) + NLMISC::CMatrix matnel = matr * matovr * coordsys; + NLMISC::CQuat finalquat = matnel.getRot(); + m_OrientationCache = finalquat; + m_OrientationCached = true; + return finalquat; +} + +/// Get GUI shift +void CStereoLibVR::getInterface2DShift(uint cid, float &x, float &y, float distance) const +{ +#if 0 + + // todo: take into account m_EyePosition + + NLMISC::CVector vector = CVector(0.f, -distance, 0.f); + NLMISC::CQuat rot = getOrientation(); + rot.invert(); + NLMISC::CMatrix mat; + mat.rotate(rot); + //if (m_Stage % 2) mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); + //else mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f)); + mat.translate(vector); + CVector proj = CStereoOVR::getCurrentFrustum(cid).project(mat.getPos()); + + NLMISC::CVector ipd; + if (m_Stage % 2) ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f); + else ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f); + CVector projipd = CStereoOVR::getCurrentFrustum(cid).project(vector + ipd); + CVector projvec = CStereoOVR::getCurrentFrustum(cid).project(vector); + + x = (proj.x + projipd.x - projvec.x - 0.5f); + y = (proj.y + projipd.y - projvec.y - 0.5f); + +#elif 1 + + // Alternative method + // todo: take into account m_EyePosition + + NLMISC::CVector vec = CVector(0.f, -distance, 0.f); + NLMISC::CVector ipd; + if (m_Stage % 2) ipd = CVector((m_DevicePtr->InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f); + else ipd = CVector((m_DevicePtr->InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f); + + + NLMISC::CQuat rot = getOrientation(); + NLMISC::CQuat modrot = NLMISC::CQuat(CVector(0.f, 1.f, 0.f), NLMISC::Pi); + rot = rot * modrot; + float p = NLMISC::Pi + atan2f(2.0f * ((rot.x * rot.y) + (rot.z * rot.w)), 1.0f - 2.0f * ((rot.y * rot.y) + (rot.w * rot.w))); + if (p > NLMISC::Pi) p -= NLMISC::Pi * 2.0f; + float t = -atan2f(2.0f * ((rot.x * rot.w) + (rot.y * rot.z)), 1.0f - 2.0f * ((rot.z * rot.z) + (rot.w * rot.w)));// // asinf(2.0f * ((rot.x * rot.z) - (rot.w * rot.y))); + + CVector rotshift = CVector(p, 0.f, t) * -distance; + + CVector proj = CStereoLibVR::getCurrentFrustum(cid).project(vec + ipd + rotshift); + + x = (proj.x - 0.5f); + y = (proj.y - 0.5f); + +#endif +} + +void CStereoLibVR::setEyePosition(const NLMISC::CVector &v) +{ + m_EyePosition = v; +} + +const NLMISC::CVector &CStereoLibVR::getEyePosition() const +{ + return m_EyePosition; +} + +void CStereoLibVR::setScale(float s) +{ + m_EyePosition = m_EyePosition * (s / m_Scale); + m_Scale = s; +} + +void CStereoLibVR::listDevices(std::vector &devicesOut) +{ + // For now, LibVR doesn't support multiple devices + struct hmd *hmd = hmd_open_first(0); + if (hmd) + { + CStereoDeviceInfo deviceInfoOut; + CStereoLibVRDeviceHandle *handle = new CStereoLibVRDeviceHandle(); + deviceInfoOut.Factory = static_cast(handle); + deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; + deviceInfoOut.Library = CStereoDeviceInfo::LibVR; + //TODO: manufacturer, produc name + //TODO: serial + devicesOut.push_back(deviceInfoOut); + hmd_close(hmd); + } +} + +bool CStereoLibVR::isLibraryInUse() +{ + nlassert(s_DeviceCounter >= 0); + return s_DeviceCounter > 0; +} + +void CStereoLibVR::releaseLibrary() +{ + nlassert(s_DeviceCounter == 0); +} + +bool CStereoLibVR::isDeviceCreated() +{ + return m_DevicePtr->HMDDevice != NULL; +} + +} /* namespace NL3D */ + +#endif /* HAVE_LIBVR */ + +/* end of file */ diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp new file mode 100644 index 000000000..46a8d147c --- /dev/null +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -0,0 +1,850 @@ +/** + * \file stereo_ovr.cpp + * \brief CStereoOVR + * \date 2013-06-25 22:22GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ + +/* + * Copyright (C) 2013 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + * + * Linking this library statically or dynamically with other modules + * is making a combined work based on this library. Thus, the terms + * and conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give + * you permission to link this library with the Oculus SDK to produce + * an executable, regardless of the license terms of the Oculus SDK, + * and distribute linked combinations including the two, provided that + * you also meet the terms and conditions of the license of the Oculus + * SDK. You must obey the GNU General Public License in all respects + * for all of the code used other than the Oculus SDK. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. + */ + +#ifdef HAVE_LIBOVR + +#include +#include + +// STL includes +#include + +// External includes +#include + +// NeL includes +// #include +#include +#include +#include +#include +#include +#include +#include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +extern const char *g_StereoOVR_fp40; +extern const char *g_StereoOVR_arbfp1; +extern const char *g_StereoOVR_ps_2_0; +extern const char *g_StereoOVR_glsl330f; + +namespace { + +class CStereoOVRLog : public OVR::Log +{ +public: + CStereoOVRLog(unsigned logMask = OVR::LogMask_All) : OVR::Log(logMask) + { + + } + + virtual void LogMessageVarg(OVR::LogMessageType messageType, const char* fmt, va_list argList) + { + if (NLMISC::INelContext::isContextInitialised()) + { + char buffer[MaxLogBufferMessageSize]; + FormatLog(buffer, MaxLogBufferMessageSize, messageType, fmt, argList); + if (IsDebugMessage(messageType)) + NLMISC::INelContext::getInstance().getDebugLog()->displayNL("OVR: %s", buffer); + else + NLMISC::INelContext::getInstance().getInfoLog()->displayNL("OVR: %s", buffer); + } + } +}; + +CStereoOVRLog *s_StereoOVRLog = NULL; +OVR::Ptr s_DeviceManager; + +class CStereoOVRSystem +{ +public: + ~CStereoOVRSystem() + { + Release(); + } + + void Init() + { + if (!s_StereoOVRLog) + { + nldebug("Initialize OVR"); + s_StereoOVRLog = new CStereoOVRLog(); + } + if (!OVR::System::IsInitialized()) + OVR::System::Init(s_StereoOVRLog); + if (!s_DeviceManager) + s_DeviceManager = OVR::DeviceManager::Create(); + } + + void Release() + { + if (s_DeviceManager) + { + nldebug("Release OVR"); + s_DeviceManager->Release(); + } + s_DeviceManager.Clear(); + if (OVR::System::IsInitialized()) + OVR::System::Destroy(); + if (s_StereoOVRLog) + nldebug("Release OVR Ok"); + delete s_StereoOVRLog; + s_StereoOVRLog = NULL; + } +}; + +CStereoOVRSystem s_StereoOVRSystem; + +sint s_DeviceCounter = 0; + +} + +class CStereoOVRDeviceHandle : public IStereoDeviceFactory +{ +public: + // fixme: virtual destructor??? + OVR::DeviceEnumerator DeviceHandle; + IStereoDisplay *createDevice() const + { + CStereoOVR *stereo = new CStereoOVR(this); + if (stereo->isDeviceCreated()) + return stereo; + delete stereo; + return NULL; + } +}; + +class CStereoOVRDevicePtr +{ +public: + OVR::Ptr HMDDevice; + OVR::Ptr SensorDevice; + OVR::SensorFusion SensorFusion; + OVR::HMDInfo HMDInfo; +}; + +CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL), m_PixelProgram(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) +{ + ++s_DeviceCounter; + m_DevicePtr = new CStereoOVRDevicePtr(); + + OVR::DeviceEnumerator dh = handle->DeviceHandle; + m_DevicePtr->HMDDevice = dh.CreateDevice(); + + if (m_DevicePtr->HMDDevice) + { + m_DevicePtr->HMDDevice->GetDeviceInfo(&m_DevicePtr->HMDInfo); + nldebug("OVR: HScreenSize: %f, VScreenSize: %f", m_DevicePtr->HMDInfo.HScreenSize, m_DevicePtr->HMDInfo.VScreenSize); + nldebug("OVR: VScreenCenter: %f", m_DevicePtr->HMDInfo.VScreenCenter); + nldebug("OVR: EyeToScreenDistance: %f", m_DevicePtr->HMDInfo.EyeToScreenDistance); + nldebug("OVR: LensSeparationDistance: %f", m_DevicePtr->HMDInfo.LensSeparationDistance); + nldebug("OVR: InterpupillaryDistance: %f", m_DevicePtr->HMDInfo.InterpupillaryDistance); + nldebug("OVR: HResolution: %i, VResolution: %i", m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution); + nldebug("OVR: DistortionK[0]: %f, DistortionK[1]: %f", m_DevicePtr->HMDInfo.DistortionK[0], m_DevicePtr->HMDInfo.DistortionK[1]); + nldebug("OVR: DistortionK[2]: %f, DistortionK[3]: %f", m_DevicePtr->HMDInfo.DistortionK[2], m_DevicePtr->HMDInfo.DistortionK[3]); + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 160 NL3D::CStereoOVR::CStereoOVR : OVR: HScreenSize: 0.149760, VScreenSize: 0.093600 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 161 NL3D::CStereoOVR::CStereoOVR : OVR: VScreenCenter: 0.046800 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 162 NL3D::CStereoOVR::CStereoOVR : OVR: EyeToScreenDistance: 0.041000 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 163 NL3D::CStereoOVR::CStereoOVR : OVR: LensSeparationDistance: 0.063500 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 164 NL3D::CStereoOVR::CStereoOVR : OVR: InterpupillaryDistance: 0.064000 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 165 NL3D::CStereoOVR::CStereoOVR : OVR: HResolution: 1280, VResolution: 800 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 166 NL3D::CStereoOVR::CStereoOVR : OVR: DistortionK[0]: 1.000000, DistortionK[1]: 0.220000 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 167 NL3D::CStereoOVR::CStereoOVR : OVR: DistortionK[2]: 0.240000, DistortionK[3]: 0.000000 + m_DevicePtr->SensorDevice = m_DevicePtr->HMDDevice->GetSensor(); + m_DevicePtr->SensorFusion.AttachToSensor(m_DevicePtr->SensorDevice); + m_DevicePtr->SensorFusion.SetGravityEnabled(true); + m_DevicePtr->SensorFusion.SetPredictionEnabled(true); + m_DevicePtr->SensorFusion.SetYawCorrectionEnabled(true); + m_LeftViewport.init(0.f, 0.f, 0.5f, 1.0f); + m_RightViewport.init(0.5f, 0.f, 0.5f, 1.0f); + } +} + +CStereoOVR::~CStereoOVR() +{ + if (!m_BarrelMat.empty()) + { + m_BarrelMat.getObjectPtr()->setTexture(0, NULL); + m_Driver->deleteMaterial(m_BarrelMat); + } + delete m_BarrelTexU; + m_BarrelTexU = NULL; + m_BarrelTex = NULL; // CSmartPtr + + delete m_PixelProgram; + m_PixelProgram = NULL; + + m_Driver = NULL; + + if (m_DevicePtr->SensorDevice) + m_DevicePtr->SensorDevice->Release(); + m_DevicePtr->SensorDevice.Clear(); + if (m_DevicePtr->HMDDevice) + m_DevicePtr->HMDDevice->Release(); + m_DevicePtr->HMDDevice.Clear(); + + delete m_DevicePtr; + m_DevicePtr = NULL; + --s_DeviceCounter; +} + +class CPixelProgramOVR : public CPixelProgram +{ +public: + struct COVRIndices + { + uint LensCenter; + uint ScreenCenter; + uint Scale; + uint ScaleIn; + uint HmdWarpParam; + }; + + CPixelProgramOVR() + { + { + CSource *source = new CSource(); + source->Profile = glsl330f; + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_glsl330f); + addSource(source); + } + { + CSource *source = new CSource(); + source->Profile = fp40; + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_fp40); + source->ParamIndices["cLensCenter"] = 0; + source->ParamIndices["cScreenCenter"] = 1; + source->ParamIndices["cScale"] = 2; + source->ParamIndices["cScaleIn"] = 3; + source->ParamIndices["cHmdWarpParam"] = 4; + addSource(source); + } + { + CSource *source = new CSource(); + source->Profile = arbfp1; + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_arbfp1); + source->ParamIndices["cLensCenter"] = 0; + source->ParamIndices["cScreenCenter"] = 1; + source->ParamIndices["cScale"] = 2; + source->ParamIndices["cScaleIn"] = 3; + source->ParamIndices["cHmdWarpParam"] = 4; + addSource(source); + } + { + CSource *source = new CSource(); + source->Profile = ps_2_0; + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_ps_2_0); + source->ParamIndices["cLensCenter"] = 0; + source->ParamIndices["cScreenCenter"] = 1; + source->ParamIndices["cScale"] = 2; + source->ParamIndices["cScaleIn"] = 3; + source->ParamIndices["cHmdWarpParam"] = 4; + addSource(source); + } + } + + virtual ~CPixelProgramOVR() + { + + } + + virtual void buildInfo() + { + CPixelProgram::buildInfo(); + + m_OVRIndices.LensCenter = getUniformIndex("cLensCenter"); + nlassert(m_OVRIndices.LensCenter != ~0); + m_OVRIndices.ScreenCenter = getUniformIndex("cScreenCenter"); + nlassert(m_OVRIndices.ScreenCenter != ~0); + m_OVRIndices.Scale = getUniformIndex("cScale"); + nlassert(m_OVRIndices.Scale != ~0); + m_OVRIndices.ScaleIn = getUniformIndex("cScaleIn"); + nlassert(m_OVRIndices.ScaleIn != ~0); + m_OVRIndices.HmdWarpParam = getUniformIndex("cHmdWarpParam"); + nlassert(m_OVRIndices.HmdWarpParam != ~0); + } + + inline const COVRIndices &ovrIndices() { return m_OVRIndices; } + +private: + COVRIndices m_OVRIndices; + +}; + +void CStereoOVR::setDriver(NL3D::UDriver *driver) +{ + nlassert(!m_PixelProgram); + + NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + + if (drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + { + m_PixelProgram = new CPixelProgramOVR(); + if (!drvInternal->compilePixelProgram(m_PixelProgram)) + { + m_PixelProgram.kill(); + } + } + + if (m_PixelProgram) + { + m_Driver = driver; + + m_BarrelTex = new CTextureBloom(); // lol bloom + m_BarrelTex->setRenderTarget(true); + m_BarrelTex->setReleasable(false); + m_BarrelTex->resize(m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution); + m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_BarrelTex->setWrapS(ITexture::Clamp); + m_BarrelTex->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*m_BarrelTex); + m_BarrelTexU = new CTextureUser(m_BarrelTex); + + m_BarrelMat = m_Driver->createMaterial(); + m_BarrelMat.initUnlit(); + m_BarrelMat.setColor(CRGBA::White); + m_BarrelMat.setBlend (false); + m_BarrelMat.setAlphaTest (false); + NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); + barrelMat->setShader(NL3D::CMaterial::Normal); + barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero); + barrelMat->setZWrite(false); + barrelMat->setZFunc(CMaterial::always); + barrelMat->setDoubleSided(true); + barrelMat->setTexture(0, m_BarrelTex); + + m_BarrelQuadLeft.V0 = CVector(0.f, 0.f, 0.5f); + m_BarrelQuadLeft.V1 = CVector(0.5f, 0.f, 0.5f); + m_BarrelQuadLeft.V2 = CVector(0.5f, 1.f, 0.5f); + m_BarrelQuadLeft.V3 = CVector(0.f, 1.f, 0.5f); + + m_BarrelQuadRight.V0 = CVector(0.5f, 0.f, 0.5f); + m_BarrelQuadRight.V1 = CVector(1.f, 0.f, 0.5f); + m_BarrelQuadRight.V2 = CVector(1.f, 1.f, 0.5f); + m_BarrelQuadRight.V3 = CVector(0.5f, 1.f, 0.5f); + + nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // not allowed + + m_BarrelQuadLeft.Uv0 = CUV(0.f, 0.f); + m_BarrelQuadLeft.Uv1 = CUV(0.5f, 0.f); + m_BarrelQuadLeft.Uv2 = CUV(0.5f, 1.f); + m_BarrelQuadLeft.Uv3 = CUV(0.f, 1.f); + + m_BarrelQuadRight.Uv0 = CUV(0.5f, 0.f); + m_BarrelQuadRight.Uv1 = CUV(1.f, 0.f); + m_BarrelQuadRight.Uv2 = CUV(1.f, 1.f); + m_BarrelQuadRight.Uv3 = CUV(0.5f, 1.f); + } + else + { + nlwarning("VR: No pixel program support"); + } +} + +bool CStereoOVR::getScreenResolution(uint &width, uint &height) +{ + width = m_DevicePtr->HMDInfo.HResolution; + height = m_DevicePtr->HMDInfo.VResolution; + return true; +} + +void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) +{ + float ar = (float)m_DevicePtr->HMDInfo.HResolution / ((float)m_DevicePtr->HMDInfo.VResolution * 2.0f); + float fov = 2.0f * atanf((m_DevicePtr->HMDInfo.HScreenSize * 0.5f * 0.5f) / (m_DevicePtr->HMDInfo.EyeToScreenDistance)); //(float)NLMISC::Pi/2.f; // 2.0f * atanf(m_DevicePtr->HMDInfo.VScreenSize / 2.0f * m_DevicePtr->HMDInfo.EyeToScreenDistance); + m_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); + m_RightFrustum[cid] = m_LeftFrustum[cid]; + + float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f; + float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; // docs say LensSeparationDistance, why not InterpupillaryDistance? related to how the lenses work? + float projectionCenterOffset = (eyeProjectionShift / (m_DevicePtr->HMDInfo.HScreenSize * 0.5f)) * (m_LeftFrustum[cid].Right - m_LeftFrustum[cid].Left); // used logic for this one, but it ends up being the same as the one i made up + nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset); + + m_LeftFrustum[cid].Left -= projectionCenterOffset; + m_LeftFrustum[cid].Right -= projectionCenterOffset; + m_RightFrustum[cid].Left += projectionCenterOffset; + m_RightFrustum[cid].Right += projectionCenterOffset; + + // TODO: Clipping frustum should also take into account the IPD + m_ClippingFrustum[cid] = m_LeftFrustum[cid]; + m_ClippingFrustum[cid].Left = min(m_LeftFrustum[cid].Left, m_RightFrustum[cid].Left); + m_ClippingFrustum[cid].Right = max(m_LeftFrustum[cid].Right, m_RightFrustum[cid].Right); +} + +/// Get the frustum to use for clipping +void CStereoOVR::getClippingFrustum(uint cid, NL3D::UCamera *camera) const +{ + camera->setFrustum(m_ClippingFrustum[cid]); +} + +void CStereoOVR::updateCamera(uint cid, const NL3D::UCamera *camera) +{ + if (camera->getFrustum().Near != m_LeftFrustum[cid].Near + || camera->getFrustum().Far != m_LeftFrustum[cid].Far) + CStereoOVR::initCamera(cid, camera); + m_CameraMatrix[cid] = camera->getMatrix(); +} + +bool CStereoOVR::nextPass() +{ + // Do not allow weird stuff. + uint32 width, height; + m_Driver->getWindowSize(width, height); + nlassert(width == m_DevicePtr->HMDInfo.HResolution); + nlassert(height == m_DevicePtr->HMDInfo.VResolution); + + if (m_Driver->getPolygonMode() == UDriver::Filled) + { + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + // stage 1: + // (initBloom) + // clear buffer + // draw scene left + return true; + case 1: + ++m_Stage; + m_SubStage = 0; + // stage 2: + // draw scene right + return true; + case 2: + ++m_Stage; + m_SubStage = 0; + // stage 3: + // (endBloom) + // draw interface 3d left + return true; + case 3: + ++m_Stage; + m_SubStage = 0; + // stage 4: + // draw interface 3d right + return true; + case 4: + ++m_Stage; + m_SubStage = 0; + // stage 5: + // (endInterfacesDisplayBloom) + // draw interface 2d left + return true; + case 5: + ++m_Stage; + m_SubStage = 0; + // stage 6: + // draw interface 2d right + return true; + case 6: + m_Stage = 0; + m_SubStage = 0; + // present + m_OrientationCached = false; + return false; + } + } + else + { + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + return true; + case 1: + m_Stage = 0; + m_SubStage = 0; + return false; + } + } + nlerror("Invalid stage"); + m_Stage = 0; + m_SubStage = 0; + m_OrientationCached = false; + return false; +} + +const NL3D::CViewport &CStereoOVR::getCurrentViewport() const +{ + if (m_Stage % 2) return m_LeftViewport; + else return m_RightViewport; +} + +const NL3D::CFrustum &CStereoOVR::getCurrentFrustum(uint cid) const +{ + if (m_Stage % 2) return m_LeftFrustum[cid]; + else return m_RightFrustum[cid]; +} + +void CStereoOVR::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const +{ + if (m_Stage % 2) camera->setFrustum(m_LeftFrustum[cid]); + else camera->setFrustum(m_RightFrustum[cid]); +} + +void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const +{ + CMatrix translate; + if (m_Stage % 2) translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f)); + else translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f)); + CMatrix mat = m_CameraMatrix[cid] * translate; + if (camera->getTransformMode() == NL3D::UTransformable::RotQuat) + { + camera->setPos(mat.getPos()); + camera->setRotQuat(mat.getRot()); + } + else + { + // camera->setTransformMode(NL3D::UTransformable::DirectMatrix); + camera->setMatrix(mat); + } +} + +bool CStereoOVR::wantClear() +{ + switch (m_Stage) + { + case 1: + m_SubStage = 1; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoOVR::wantScene() +{ + switch (m_Stage) + { + case 1: + case 2: + m_SubStage = 2; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoOVR::wantInterface3D() +{ + switch (m_Stage) + { + case 3: + case 4: + m_SubStage = 3; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoOVR::wantInterface2D() +{ + switch (m_Stage) + { + case 5: + case 6: + m_SubStage = 4; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + + +/// Returns non-NULL if a new render target was set +bool CStereoOVR::beginRenderTarget() +{ + // render target always set before driver clear + // nlassert(m_SubStage <= 1); + if (m_Driver && m_Stage == 1 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + static_cast(m_Driver)->setRenderTarget(*m_BarrelTexU, 0, 0, 0, 0); + return true; + } + return false; +} + +/// Returns true if a render target was fully drawn +bool CStereoOVR::endRenderTarget() +{ + // after rendering of course + // nlassert(m_SubStage > 1); + if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui + { + CTextureUser cu; + (static_cast(m_Driver))->setRenderTarget(cu); + bool fogEnabled = m_Driver->fogEnabled(); + m_Driver->enableFog(false); + + m_Driver->setMatrixMode2D11(); + CViewport vp = CViewport(); + m_Driver->setViewport(vp); + uint32 width, height; + m_Driver->getWindowSize(width, height); + NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); + NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); + barrelMat->setTexture(0, m_BarrelTex); + + drvInternal->activePixelProgram(m_PixelProgram); + + float w = float(m_BarrelQuadLeft.V1.x),// / float(width), + h = float(m_BarrelQuadLeft.V2.y),// / float(height), + x = float(m_BarrelQuadLeft.V0.x),/// / float(width), + y = float(m_BarrelQuadLeft.V0.y);// / float(height); + + float lensOffset = m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; + float lensShift = m_DevicePtr->HMDInfo.HScreenSize * 0.25f - lensOffset; + float lensViewportShift = 4.0f * lensShift / m_DevicePtr->HMDInfo.HScreenSize; + + float lensCenterX = x + (w + lensViewportShift * 0.5f) * 0.5f; + float lensCenterY = y + h * 0.5f; + float screenCenterX = x + w * 0.5f; + float screenCenterY = y + h * 0.5f; + float scaleX = (w / 2); + float scaleY = (h / 2); + float scaleInX = (2 / w); + float scaleInY = (2 / h); + + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().LensCenter, + lensCenterX, lensCenterY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().ScreenCenter, + screenCenterX, screenCenterY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().Scale, + scaleX, scaleY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().ScaleIn, + scaleInX, scaleInY); + + + drvInternal->setUniform4fv(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().HmdWarpParam, + 1, m_DevicePtr->HMDInfo.DistortionK); + + m_Driver->drawQuad(m_BarrelQuadLeft, m_BarrelMat); + + x = w; + lensCenterX = x + (w - lensViewportShift * 0.5f) * 0.5f; + screenCenterX = x + w * 0.5f; + + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().LensCenter, + lensCenterX, lensCenterY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().ScreenCenter, + screenCenterX, screenCenterY); + + + m_Driver->drawQuad(m_BarrelQuadRight, m_BarrelMat); + + drvInternal->activePixelProgram(NULL); + m_Driver->enableFog(fogEnabled); + + return true; + } + return false; +} + +NLMISC::CQuat CStereoOVR::getOrientation() const +{ + if (m_OrientationCached) + return m_OrientationCache; + + OVR::Quatf quatovr = m_DevicePtr->SensorFusion.GetPredictedOrientation(); + NLMISC::CMatrix coordsys; + float csys[] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + coordsys.set(csys); + NLMISC::CMatrix matovr; + matovr.setRot(NLMISC::CQuat(quatovr.x, quatovr.y, quatovr.z, quatovr.w)); + NLMISC::CMatrix matr; + matr.rotateX(NLMISC::Pi * 0.5f); // fix this properly... :) (note: removing this allows you to use rift while lying down) + NLMISC::CMatrix matnel = matr * matovr * coordsys; + NLMISC::CQuat finalquat = matnel.getRot(); + m_OrientationCache = finalquat; + m_OrientationCached = true; + return finalquat; +} + +/// Get GUI shift +void CStereoOVR::getInterface2DShift(uint cid, float &x, float &y, float distance) const +{ +#if 0 + + // todo: take into account m_EyePosition + + NLMISC::CVector vector = CVector(0.f, -distance, 0.f); + NLMISC::CQuat rot = getOrientation(); + rot.invert(); + NLMISC::CMatrix mat; + mat.rotate(rot); + //if (m_Stage % 2) mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); + //else mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f)); + mat.translate(vector); + CVector proj = CStereoOVR::getCurrentFrustum(cid).project(mat.getPos()); + + NLMISC::CVector ipd; + if (m_Stage % 2) ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f); + else ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f); + CVector projipd = CStereoOVR::getCurrentFrustum(cid).project(vector + ipd); + CVector projvec = CStereoOVR::getCurrentFrustum(cid).project(vector); + + x = (proj.x + projipd.x - projvec.x - 0.5f); + y = (proj.y + projipd.y - projvec.y - 0.5f); + +#elif 1 + + // Alternative method + // todo: take into account m_EyePosition + + NLMISC::CVector vec = CVector(0.f, -distance, 0.f); + NLMISC::CVector ipd; + if (m_Stage % 2) ipd = CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f); + else ipd = CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f); + + + NLMISC::CQuat rot = getOrientation(); + NLMISC::CQuat modrot = NLMISC::CQuat(CVector(0.f, 1.f, 0.f), NLMISC::Pi); + rot = rot * modrot; + float p = NLMISC::Pi + atan2f(2.0f * ((rot.x * rot.y) + (rot.z * rot.w)), 1.0f - 2.0f * ((rot.y * rot.y) + (rot.w * rot.w))); + if (p > NLMISC::Pi) p -= NLMISC::Pi * 2.0f; + float t = -atan2f(2.0f * ((rot.x * rot.w) + (rot.y * rot.z)), 1.0f - 2.0f * ((rot.z * rot.z) + (rot.w * rot.w)));// // asinf(2.0f * ((rot.x * rot.z) - (rot.w * rot.y))); + + CVector rotshift = CVector(p, 0.f, t) * -distance; + + CVector proj = CStereoOVR::getCurrentFrustum(cid).project(vec + ipd + rotshift); + + x = (proj.x - 0.5f); + y = (proj.y - 0.5f); + +#endif +} + +void CStereoOVR::setEyePosition(const NLMISC::CVector &v) +{ + m_EyePosition = v; +} + +const NLMISC::CVector &CStereoOVR::getEyePosition() const +{ + return m_EyePosition; +} + +void CStereoOVR::setScale(float s) +{ + m_EyePosition = m_EyePosition * (s / m_Scale); + m_Scale = s; +} + +void CStereoOVR::listDevices(std::vector &devicesOut) +{ + s_StereoOVRSystem.Init(); + OVR::DeviceEnumerator devices = s_DeviceManager->EnumerateDevices(); + uint id = 1; + do + { + CStereoDeviceInfo deviceInfoOut; + OVR::DeviceInfo deviceInfo; + if (devices.IsAvailable()) + { + devices.GetDeviceInfo(&deviceInfo); + CStereoOVRDeviceHandle *handle = new CStereoOVRDeviceHandle(); + deviceInfoOut.Factory = static_cast(handle); + handle->DeviceHandle = devices; + deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; // 1; // OVR::HMDDevice + deviceInfoOut.Library = CStereoDeviceInfo::OVR; // "Oculus SDK"; + deviceInfoOut.Manufacturer = deviceInfo.Manufacturer; + deviceInfoOut.ProductName = deviceInfo.ProductName; + stringstream ser; + ser << id; + deviceInfoOut.Serial = ser.str(); // can't get the real serial from the sdk... + devicesOut.push_back(deviceInfoOut); + ++id; + } + + } while (devices.Next()); +} + +bool CStereoOVR::isLibraryInUse() +{ + nlassert(s_DeviceCounter >= 0); + return s_DeviceCounter > 0; +} + +void CStereoOVR::releaseLibrary() +{ + nlassert(s_DeviceCounter == 0); + s_StereoOVRSystem.Release(); +} + +bool CStereoOVR::isDeviceCreated() +{ + return m_DevicePtr->HMDDevice != NULL; +} + +} /* namespace NL3D */ + +#endif /* HAVE_LIBOVR */ + +/* end of file */ diff --git a/code/nel/src/3d/stereo_ovr_fp.cpp b/code/nel/src/3d/stereo_ovr_fp.cpp new file mode 100644 index 000000000..940be0bfe --- /dev/null +++ b/code/nel/src/3d/stereo_ovr_fp.cpp @@ -0,0 +1,249 @@ +/************************************************************************************ + +Filename : stereo_ovf_fp.cpp +Content : Barrel fragment program compiled to a blob of assembly +Created : July 01, 2013 +Modified by : Jan Boon (Kaetemi) + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +namespace NL3D { +const char *g_StereoOVR_fp40 = + "!!ARBfp1.0\n" + "OPTION NV_fragment_program2;\n" + //# cgc version 3.1.0013, build date Apr 18 2012 + //# command line args: -profile fp40 + //# source file: pp_oculus_vr.cg + //#vendor NVIDIA Corporation + //#version 3.1.0.13 + //#profile fp40 + //#program pp_oculus_vr + //#semantic pp_oculus_vr.cLensCenter + //#semantic pp_oculus_vr.cScreenCenter + //#semantic pp_oculus_vr.cScale + //#semantic pp_oculus_vr.cScaleIn + //#semantic pp_oculus_vr.cHmdWarpParam + //#semantic pp_oculus_vr.cTex0 : TEX0 + //#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //#var float2 cLensCenter : : c[0] : 1 : 1 + //#var float2 cScreenCenter : : c[1] : 2 : 1 + //#var float2 cScale : : c[2] : 3 : 1 + //#var float2 cScaleIn : : c[3] : 4 : 1 + //#var float4 cHmdWarpParam : : c[4] : 5 : 1 + //#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 + //#var float4 oCol : $vout.COLOR : COL : 7 : 1 + //#const c[5] = 0.25 0.5 0 + "PARAM c[6] = { program.env[0..4],\n" // program.local->program.env! + " { 0.25, 0.5, 0 } };\n" + "TEMP R0;\n" + "TEMP R1;\n" + "SHORT TEMP H0;\n" + "TEMP RC;\n" + "TEMP HC;\n" + "OUTPUT oCol = result.color;\n" + "ADDR R0.xy, fragment.texcoord[0], -c[0];\n" + "MULR R0.xy, R0, c[3];\n" + "MULR R0.z, R0.y, R0.y;\n" + "MADR R1.x, R0, R0, R0.z;\n" + "MULR R0.zw, R1.x, c[4].xywz;\n" + "MADR R1.y, R1.x, c[4], c[4].x;\n" + "MADR R0.w, R0, R1.x, R1.y;\n" + "MULR R0.z, R0, R1.x;\n" + "MADR R0.z, R0, R1.x, R0.w;\n" + "MULR R1.xy, R0, R0.z;\n" + "MOVR R0.xy, c[5];\n" + "ADDR R1.zw, R0.xyxy, c[1].xyxy;\n" + "MOVR R0.zw, c[0].xyxy;\n" + "MADR R0.zw, R1.xyxy, c[2].xyxy, R0;\n" + "MINR R1.xy, R0.zwzw, R1.zwzw;\n" + "ADDR R0.xy, -R0, c[1];\n" + "MAXR R0.xy, R0, R1;\n" + "SEQR H0.xy, R0, R0.zwzw;\n" + "MULXC HC.x, H0, H0.y;\n" + "IF EQ.x;\n" + "MOVR oCol, c[5].z;\n" + "ELSE;\n" + "TEX oCol, R0.zwzw, texture[0], 2D;\n" + "ENDIF;\n" + "END\n"; + //# 24 instructions, 2 R-regs, 1 H-regs + +const char *g_StereoOVR_arbfp1 = + "!!ARBfp1.0\n" + //# cgc version 3.1.0013, build date Apr 18 2012 + //# command line args: -profile arbfp1 + //# source file: pp_oculus_vr.cg + //#vendor NVIDIA Corporation + //#version 3.1.0.13 + //#profile arbfp1 + //#program pp_oculus_vr + //#semantic pp_oculus_vr.cLensCenter + //#semantic pp_oculus_vr.cScreenCenter + //#semantic pp_oculus_vr.cScale + //#semantic pp_oculus_vr.cScaleIn + //#semantic pp_oculus_vr.cHmdWarpParam + //#semantic pp_oculus_vr.cTex0 : TEX0 + //#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //#var float2 cLensCenter : : c[0] : 1 : 1 + //#var float2 cScreenCenter : : c[1] : 2 : 1 + //#var float2 cScale : : c[2] : 3 : 1 + //#var float2 cScaleIn : : c[3] : 4 : 1 + //#var float4 cHmdWarpParam : : c[4] : 5 : 1 + //#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 + //#var float4 oCol : $vout.COLOR : COL : 7 : 1 + //#const c[5] = 0.25 0.5 0 1 + "PARAM c[6] = { program.env[0..4],\n" + " { 0.25, 0.5, 0, 1 } };\n" + "TEMP R0;\n" + "TEMP R1;\n" + "ADD R0.xy, fragment.texcoord[0], -c[0];\n" + "MUL R0.xy, R0, c[3];\n" + "MUL R0.z, R0.y, R0.y;\n" + "MAD R0.z, R0.x, R0.x, R0;\n" + "MUL R0.w, R0.z, c[4];\n" + "MUL R0.w, R0, R0.z;\n" + "MAD R1.y, R0.z, c[4], c[4].x;\n" + "MUL R1.x, R0.z, c[4].z;\n" + "MAD R1.x, R0.z, R1, R1.y;\n" + "MAD R0.z, R0.w, R0, R1.x;\n" + "MUL R0.xy, R0, R0.z;\n" + "MOV R0.zw, c[5].xyxy;\n" + "ADD R1.xy, R0.zwzw, c[1];\n" + "MUL R0.xy, R0, c[2];\n" + "ADD R0.xy, R0, c[0];\n" + "MIN R1.xy, R1, R0;\n" + "ADD R0.zw, -R0, c[1].xyxy;\n" + "MAX R0.zw, R0, R1.xyxy;\n" + "ADD R0.zw, R0, -R0.xyxy;\n" + "ABS R0.zw, R0;\n" + "CMP R0.zw, -R0, c[5].z, c[5].w;\n" + "MUL R0.z, R0, R0.w;\n" + "ABS R0.z, R0;\n" + "CMP R0.z, -R0, c[5], c[5].w;\n" + "ABS R1.x, R0.z;\n" + "TEX R0, R0, texture[0], 2D;\n" + "CMP R1.x, -R1, c[5].z, c[5].w;\n" + "CMP result.color, -R1.x, R0, c[5].z;\n" + "END\n"; + //# 28 instructions, 2 R-regs + +const char *g_StereoOVR_ps_2_0 = + "ps_2_0\n" + // cgc version 3.1.0013, build date Apr 18 2012 + // command line args: -profile ps_2_0 + // source file: pp_oculus_vr.cg + //vendor NVIDIA Corporation + //version 3.1.0.13 + //profile ps_2_0 + //program pp_oculus_vr + //semantic pp_oculus_vr.cLensCenter + //semantic pp_oculus_vr.cScreenCenter + //semantic pp_oculus_vr.cScale + //semantic pp_oculus_vr.cScaleIn + //semantic pp_oculus_vr.cHmdWarpParam + //semantic pp_oculus_vr.cTex0 : TEX0 + //var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //var float2 cLensCenter : : c[0] : 1 : 1 + //var float2 cScreenCenter : : c[1] : 2 : 1 + //var float2 cScale : : c[2] : 3 : 1 + //var float2 cScaleIn : : c[3] : 4 : 1 + //var float4 cHmdWarpParam : : c[4] : 5 : 1 + //var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 + //var float4 oCol : $vout.COLOR : COL : 7 : 1 + //const c[5] = -0.25 -0.5 0.25 0.5 + //const c[6] = 1 0 + "dcl_2d s0\n" + "def c5, -0.25000000, -0.50000000, 0.25000000, 0.50000000\n" + "def c6, 1.00000000, 0.00000000, 0, 0\n" + "dcl t0.xy\n" + "add r0.xy, t0, -c0\n" + "mul r4.xy, r0, c3\n" + "mul r0.x, r4.y, r4.y\n" + "mad r0.x, r4, r4, r0\n" + "mul r1.x, r0, c4.w\n" + "mul r1.x, r1, r0\n" + "mad r3.x, r0, c4.y, c4\n" + "mul r2.x, r0, c4.z\n" + "mad r2.x, r0, r2, r3\n" + "mad r0.x, r1, r0, r2\n" + "mul r0.xy, r4, r0.x\n" + "mul r0.xy, r0, c2\n" + "add r3.xy, r0, c0\n" + "mov r1.x, c5.z\n" + "mov r1.y, c5.w\n" + "mov r2.xy, c1\n" + "add r2.xy, r1, r2\n" + "mov r1.xy, c1\n" + "min r2.xy, r2, r3\n" + "add r1.xy, c5, r1\n" + "max r1.xy, r1, r2\n" + "add r1.xy, r1, -r3\n" + "abs r1.xy, r1\n" + "cmp r1.xy, -r1, c6.x, c6.y\n" + "mul_pp r1.x, r1, r1.y\n" + "abs_pp r1.x, r1\n" + "cmp_pp r1.x, -r1, c6, c6.y\n" + "abs_pp r1.x, r1\n" + "texld r0, r3, s0\n" + "cmp r0, -r1.x, r0, c6.y\n" + "mov oC0, r0\n"; + +const char *g_StereoOVR_glsl330f = + "#version 330\n" + "\n" + "bool _TMP2;\n" + "bvec2 _TMP1;\n" + "vec2 _TMP3;\n" + "uniform vec2 cLensCenter;\n" + "uniform vec2 cScreenCenter;\n" + "uniform vec2 cScale;\n" + "uniform vec2 cScaleIn;\n" + "uniform vec4 cHmdWarpParam;\n" + "uniform sampler2D nlTex0;\n" + "vec2 _TMP10;\n" + "vec2 _b0011;\n" + "vec2 _a0011;\n" + "in vec4 nlTexCoord0;\n" + "out vec4 nlCol;\n" + "\n" + "void main()\n" + "{\n" + " vec2 _theta;\n" + " float _rSq;\n" + " vec2 _theta1;\n" + " vec2 _tc;\n" + "\n" + " _theta = (nlTexCoord0.xy - cLensCenter)*cScaleIn;\n" + " _rSq = _theta.x*_theta.x + _theta.y*_theta.y;\n" + " _theta1 = _theta*(cHmdWarpParam.x + cHmdWarpParam.y*_rSq + cHmdWarpParam.z*_rSq*_rSq + cHmdWarpParam.w*_rSq*_rSq*_rSq);\n" + " _tc = cLensCenter + cScale*_theta1;\n" + " _a0011 = cScreenCenter - vec2( 0.25, 0.5);\n" + " _b0011 = cScreenCenter + vec2( 0.25, 0.5);\n" + " _TMP3 = min(_b0011, _tc);\n" + " _TMP10 = max(_a0011, _TMP3);\n" + " _TMP1 = bvec2(_TMP10.x == _tc.x, _TMP10.y == _tc.y);\n" + " _TMP2 = _TMP1.x && _TMP1.y;\n" + " if (!_TMP2) {\n" + " nlCol = vec4(0, 0, 0, 0);\n" + " } else {\n" + " nlCol = texture(nlTex0, _tc);\n" + " }\n" + "}\n"; + +} + +/* end of file */ diff --git a/code/nel/src/3d/tile_far_bank.cpp b/code/nel/src/3d/tile_far_bank.cpp index 75a758560..e62903904 100644 --- a/code/nel/src/3d/tile_far_bank.cpp +++ b/code/nel/src/3d/tile_far_bank.cpp @@ -104,8 +104,8 @@ const sint CTileFarBank::_Version=0x0; void CTileFarBank::serial(NLMISC::IStream &f) throw(NLMISC::EStream) { // Write/Check "FAR_BANK" in header of the stream - f.serialCheck ((uint32)'_RAF'); - f.serialCheck ((uint32)'KNAB'); + f.serialCheck (NELID("_RAF")); + f.serialCheck (NELID("KNAB")); // Serial version (void)f.serialVersion(_Version); diff --git a/code/nel/src/3d/vegetable_manager.cpp b/code/nel/src/3d/vegetable_manager.cpp index fe1c63dc4..ba44a766f 100644 --- a/code/nel/src/3d/vegetable_manager.cpp +++ b/code/nel/src/3d/vegetable_manager.cpp @@ -126,9 +126,7 @@ CVegetableManager::~CVegetableManager() // delete All VP for(sint i=0; i Profile = nelvp; + source->DisplayName = "nelvp/Veget"; + + // Init the Vertex Program. + string vpgram; + // start always with Bend. + if( vpType==NL3D_VEGETABLE_RDRPASS_LIGHTED || vpType==NL3D_VEGETABLE_RDRPASS_LIGHTED_2SIDED ) + { + source->DisplayName += "/Bend"; + vpgram= NL3D_BendProgram; + } + else + { + source->DisplayName += "/FastBend"; + vpgram= NL3D_FastBendProgram; + } + // combine the VP according to Type + switch(vpType) + { + case NL3D_VEGETABLE_RDRPASS_LIGHTED: + case NL3D_VEGETABLE_RDRPASS_LIGHTED_2SIDED: + source->DisplayName += "/Lighted"; + vpgram+= string(NL3D_LightedStartVegetableProgram); + break; + case NL3D_VEGETABLE_RDRPASS_UNLIT: + case NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED: + source->DisplayName += "/Unlit"; + vpgram+= string(NL3D_UnlitVegetableProgram); + break; + case NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED_ZSORT: + source->DisplayName += "/UnlitAlphaBlend"; + vpgram+= string(NL3D_UnlitAlphaBlendVegetableProgram); + break; + } -// *************************************************************************** -void CVegetableManager::initVertexProgram(uint vpType, bool fogEnabled) -{ - nlassert(_LastDriver); // update driver should have been called at least once ! - // Init the Vertex Program. - string vpgram; - // start always with Bend. - if( vpType==NL3D_VEGETABLE_RDRPASS_LIGHTED || vpType==NL3D_VEGETABLE_RDRPASS_LIGHTED_2SIDED ) - vpgram= NL3D_BendProgram; - else - vpgram= NL3D_FastBendProgram; - - // combine the VP according to Type - switch(vpType) - { - case NL3D_VEGETABLE_RDRPASS_LIGHTED: - case NL3D_VEGETABLE_RDRPASS_LIGHTED_2SIDED: - vpgram+= string(NL3D_LightedStartVegetableProgram); - break; - case NL3D_VEGETABLE_RDRPASS_UNLIT: - case NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED: - vpgram+= string(NL3D_UnlitVegetableProgram); - break; - case NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED_ZSORT: - vpgram+= string(NL3D_UnlitAlphaBlendVegetableProgram); - break; - } + // common end of VP + vpgram+= string(NL3D_CommonEndVegetableProgram); - // common end of VP - vpgram+= string(NL3D_CommonEndVegetableProgram); + if (fogEnabled) + { + source->DisplayName += "/Fog"; + vpgram+= string(NL3D_VegetableProgramFog); + } - if (fogEnabled) - { - vpgram+= string(NL3D_VegetableProgramFog); + vpgram+="\nEND\n"; + + source->setSource(vpgram); + + source->ParamIndices["modelViewProjection"] = 0; + source->ParamIndices["fog"] = 6; + source->ParamIndices["programConstants0"] = 8; + source->ParamIndices["directionalLight"] = 9; + source->ParamIndices["viewCenter"] = 10; + source->ParamIndices["negInvTransDist"] = 11; + source->ParamIndices["angleAxis"] = 16; + source->ParamIndices["wind"] = 17; + source->ParamIndices["cosCoeff0"] = 18; + source->ParamIndices["cosCoeff1"] = 19; + source->ParamIndices["cosCoeff2"] = 20; + source->ParamIndices["quatConstants"] = 21; + source->ParamIndices["piConstants"] = 22; + source->ParamIndices["lutSize"] = 23; + for (uint i = 0; i < NL3D_VEGETABLE_VP_LUT_SIZE; ++i) + { + source->ParamIndices[NLMISC::toString("lut[%i]", i)] = 32 + i; + } + + addSource(source); + } + // TODO_VP_GLSL } + virtual ~CVertexProgramVeget() + { - vpgram+="\nEND\n"; + } + virtual void buildInfo() + { + m_Idx.ProgramConstants0 = getUniformIndex("programConstants0"); + nlassert(m_Idx.ProgramConstants0 != ~0); + m_Idx.DirectionalLight = getUniformIndex("directionalLight"); + nlassert(m_Idx.DirectionalLight != ~0); + m_Idx.ViewCenter = getUniformIndex("viewCenter"); + nlassert(m_Idx.ViewCenter != ~0); + m_Idx.NegInvTransDist = getUniformIndex("negInvTransDist"); + nlassert(m_Idx.NegInvTransDist != ~0); + m_Idx.AngleAxis = getUniformIndex("angleAxis"); + nlassert(m_Idx.AngleAxis != ~0); + m_Idx.Wind = getUniformIndex("wind"); + nlassert(m_Idx.Wind != ~0); + m_Idx.CosCoeff0 = getUniformIndex("cosCoeff0"); + nlassert(m_Idx.CosCoeff0 != ~0); + m_Idx.CosCoeff1 = getUniformIndex("cosCoeff1"); + nlassert(m_Idx.CosCoeff1 != ~0); + m_Idx.CosCoeff2 = getUniformIndex("cosCoeff2"); + nlassert(m_Idx.CosCoeff2 != ~0); + m_Idx.QuatConstants = getUniformIndex("quatConstants"); + nlassert(m_Idx.QuatConstants != ~0); + m_Idx.PiConstants = getUniformIndex("piConstants"); + nlassert(m_Idx.PiConstants != ~0); + m_Idx.LUTSize = getUniformIndex("lutSize"); + nlassert(m_Idx.LUTSize != ~0); + for (uint i = 0; i < NL3D_VEGETABLE_VP_LUT_SIZE; ++i) + { + m_Idx.LUT[i] = getUniformIndex(NLMISC::toString("lut[%i]", i)); + nlassert(m_Idx.LUT[i] != ~0); + } + } + const CIdx &idx() const { return m_Idx; } +private: + CIdx m_Idx; +}; +// *************************************************************************** +void CVegetableManager::initVertexProgram(uint vpType, bool fogEnabled) +{ + nlassert(_LastDriver); // update driver should have been called at least once ! + // create VP. - _VertexProgram[vpType][fogEnabled ? 1 : 0] = new CVertexProgram(vpgram.c_str()); - + _VertexProgram[vpType][fogEnabled ? 1 : 0] = new CVertexProgramVeget(vpType, fogEnabled); } @@ -1756,42 +1864,48 @@ public: // *************************************************************************** -void CVegetableManager::setupVertexProgramConstants(IDriver *driver) +void CVegetableManager::setupVertexProgramConstants(IDriver *driver, bool fogEnabled) { + nlassert(_ActiveVertexProgram); + + // Standard // setup VertexProgram constants. // c[0..3] take the ModelViewProjection Matrix. After setupModelMatrix(); - driver->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); + driver->setUniformMatrix(IDriver::VertexProgram, _ActiveVertexProgram->getUniformIndex(CProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); // c[6] take the Fog vector. After setupModelMatrix(); - driver->setConstantFog(6); + if (fogEnabled) + { + driver->setUniformFog(IDriver::VertexProgram, _ActiveVertexProgram->getUniformIndex(CProgramIndex::Fog)); + } // c[8] take useful constants. - driver->setConstant(8, 0, 1, 0.5f, 2); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().ProgramConstants0, 0, 1, 0.5f, 2); // c[9] take normalized directional light - driver->setConstant(9, _DirectionalLight); + driver->setUniform3f(IDriver::VertexProgram, _ActiveVertexProgram->idx().DirectionalLight, _DirectionalLight); // c[10] take pos of camera - driver->setConstant(10, _ViewCenter); + driver->setUniform3f(IDriver::VertexProgram, _ActiveVertexProgram->idx().ViewCenter, _ViewCenter); // c[11] take factor for Blend formula - driver->setConstant(11, -1.f/NL3D_VEGETABLE_BLOCK_BLEND_TRANSITION_DIST, 0, 0, 0); + driver->setUniform1f(IDriver::VertexProgram, _ActiveVertexProgram->idx().NegInvTransDist, -1.f/NL3D_VEGETABLE_BLOCK_BLEND_TRANSITION_DIST); // Bend. // c[16]= quaternion axis. w==1, and z must be 0 - driver->setConstant( 16, _AngleAxis.x, _AngleAxis.y, _AngleAxis.z, 1); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().AngleAxis, _AngleAxis, 1); // c[17]= {timeAnim, WindPower, WindPower*(1-WindBendMin)/2, 0)} - driver->setConstant( 17, (float)_WindAnimTime, _WindPower, _WindPower*(1-_WindBendMin)/2, 0 ); + driver->setUniform3f(IDriver::VertexProgram, _ActiveVertexProgram->idx().Wind, (float)_WindAnimTime, _WindPower, _WindPower * (1 - _WindBendMin) / 2); // c[18]= High order Taylor cos coefficient: { -1/2, 1/24, -1/720, 1/40320 } - driver->setConstant( 18, -1/2.f, 1/24.f, -1/720.f, 1/40320.f ); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().CosCoeff0, -1/2.f, 1/24.f, -1/720.f, 1/40320.f ); // c[19]= Low order Taylor cos coefficient: { 1, -1/2, 1/24, -1/720 } - driver->setConstant( 19, 1, -1/2.f, 1/24.f, -1/720.f ); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().CosCoeff1, 1, -1/2.f, 1/24.f, -1/720.f ); // c[20]= Low order Taylor sin coefficient: { 1, -1/6, 1/120, -1/5040 } - driver->setConstant( 20, 1, -1/6.f, 1/120.f, -1/5040.f ); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().CosCoeff2, 1, -1/6.f, 1/120.f, -1/5040.f ); // c[21]= Special constant vector for quatToMatrix: { 0, 1, -1, 0 } - driver->setConstant( 21, 0.f, 1.f, -1.f, 0.f); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().QuatConstants, 0.f, 1.f, -1.f, 0.f); // c[22]= {0.5f, Pi, 2*Pi, 1/(2*Pi)} - driver->setConstant( 22, 0.5f, (float)Pi, (float)(2*Pi), (float)(1/(2*Pi)) ); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().PiConstants, 0.5f, (float)Pi, (float)(2*Pi), (float)(1/(2*Pi))); // c[23]= {NL3D_VEGETABLE_VP_LUT_SIZE, 0, 0, 0}. NL3D_VEGETABLE_VP_LUT_SIZE==64. - driver->setConstant( 23, NL3D_VEGETABLE_VP_LUT_SIZE, 0.f, 0.f, 0.f ); + driver->setUniform1f(IDriver::VertexProgram, _ActiveVertexProgram->idx().LUTSize, NL3D_VEGETABLE_VP_LUT_SIZE); // Fill constant. Start at 32. @@ -1799,7 +1913,7 @@ void CVegetableManager::setupVertexProgramConstants(IDriver *driver) { CVector2f cur= _WindTable[i]; CVector2f delta= _WindDeltaTable[i]; - driver->setConstant( 32+i, cur.x, cur.y, delta.x, delta.y ); + driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().LUT[i], cur.x, cur.y, delta.x, delta.y); } } @@ -1925,10 +2039,6 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front } - // setup VP constants. - setupVertexProgramConstants(driver); - - // Setup TexEnvs for Dynamic lightmapping //-------------------- // if the dynamic lightmap is provided @@ -1968,6 +2078,12 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front _VegetableMaterial.setZWrite(true); _VegetableMaterial.setAlphaTestThreshold(0.5f); + bool uprogst = driver->isUniformProgramState(); + bool progstateset[NL3D_VEGETABLE_NRDRPASS]; + for (sint rdrPass = 0; rdrPass < NL3D_VEGETABLE_NRDRPASS; ++rdrPass) + { + progstateset[rdrPass] = false; + } /* Prefer sort with Soft / Hard first. @@ -1995,14 +2111,20 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front // set the 2Sided flag in the material _VegetableMaterial.setDoubleSided( doubleSided ); - - // Activate the unique material. - driver->setupMaterial(_VegetableMaterial); - // activate Vertex program first. //nlinfo("\nSTARTVP\n%s\nENDVP\n", _VertexProgram[rdrPass]->getProgram().c_str()); - nlverify(driver->activeVertexProgram(_VertexProgram[rdrPass][fogged ? 1 : 0])); + _ActiveVertexProgram = _VertexProgram[rdrPass][fogged ? 1 : 0]; + nlverify(driver->activeVertexProgram(_ActiveVertexProgram)); + + // Set VP constants + if (!progstateset[uprogst ? rdrPass : 0]) + { + setupVertexProgramConstants(driver, uprogst ? fogged : true); + } + + // Activate the unique material. + driver->setupMaterial(_VegetableMaterial); // Activate the good VBuffer vbAllocator.activate(); @@ -2222,6 +2344,7 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front // disable VertexProgram. driver->activeVertexProgram(NULL); + _ActiveVertexProgram = NULL; // restore Fog. @@ -2261,25 +2384,25 @@ void CVegetableManager::setupRenderStateForBlendLayerModel(IDriver *driver) // set model matrix to the manager matrix. driver->setupModelMatrix(_ManagerMatrix); - // setup VP constants. - setupVertexProgramConstants(driver); - // Setup RdrPass. //============= uint rdrPass= NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED_ZSORT; - // Activate the unique material (correclty setuped for AlphaBlend in render()). - driver->setupMaterial(_VegetableMaterial); - // activate Vertex program first. //nlinfo("\nSTARTVP\n%s\nENDVP\n", _VertexProgram[rdrPass]->getProgram().c_str()); - nlverify(driver->activeVertexProgram(_VertexProgram[rdrPass][fogged ? 1 : 0])); + _ActiveVertexProgram = _VertexProgram[rdrPass][fogged ? 1 : 0]; + nlverify(driver->activeVertexProgram(_ActiveVertexProgram)); + + // setup VP constants. + setupVertexProgramConstants(driver, fogged); - if (fogged) + /*if (fogged) // duplicate { - driver->setConstantFog(6); - } + driver->setCon/stantFog(6); + }*/ + // Activate the unique material (correclty setuped for AlphaBlend in render()). + driver->setupMaterial(_VegetableMaterial); } @@ -2302,6 +2425,7 @@ void CVegetableManager::exitRenderStateForBlendLayerModel(IDriver *driver) { // disable VertexProgram. driver->activeVertexProgram(NULL); + _ActiveVertexProgram = NULL; // restore Fog. driver->enableFog(_BkupFog); diff --git a/code/nel/src/3d/vegetable_shape.cpp b/code/nel/src/3d/vegetable_shape.cpp index 0b8697d63..7d9991b65 100644 --- a/code/nel/src/3d/vegetable_shape.cpp +++ b/code/nel/src/3d/vegetable_shape.cpp @@ -192,10 +192,10 @@ void CVegetableShape::serial(NLMISC::IStream &f) - BestSidedPreComputeLighting */ sint ver= f.serialVersion(1); - f.serialCheck((uint32)'_LEN'); - f.serialCheck((uint32)'GEV_'); - f.serialCheck((uint32)'BATE'); - f.serialCheck((uint32)'__EL'); + f.serialCheck(NELID("_LEN")); + f.serialCheck(NELID("GEV_")); + f.serialCheck(NELID("BATE")); + f.serialCheck(NELID("__EL")); f.serial(Lighted); f.serial(DoubleSided); diff --git a/code/nel/src/3d/vegetablevb_allocator.cpp b/code/nel/src/3d/vegetablevb_allocator.cpp index 9c801b179..29a03b51d 100644 --- a/code/nel/src/3d/vegetablevb_allocator.cpp +++ b/code/nel/src/3d/vegetablevb_allocator.cpp @@ -98,7 +98,9 @@ void CVegetableVBAllocator::updateDriver(IDriver *driver) _VBHardOk= false; // Driver must support VP. - nlassert(_Driver->isVertexProgramSupported()); + nlassert(_Driver->supportVertexProgram(CVertexProgram::nelvp) + // || _Driver->supportVertexProgram(CVertexProgram::glsl330v) // TODO_VP_GLSL + ); // must reallocate the VertexBuffer. if( _NumVerticesAllocated>0 ) diff --git a/code/nel/src/3d/vertex_program.cpp b/code/nel/src/3d/vertex_program.cpp index 9e7587069..d0c0cfb79 100644 --- a/code/nel/src/3d/vertex_program.cpp +++ b/code/nel/src/3d/vertex_program.cpp @@ -24,34 +24,28 @@ namespace NL3D { - // *************************************************************************** -IVertexProgramDrvInfos::IVertexProgramDrvInfos (IDriver *drv, ItVtxPrgDrvInfoPtrList it) -{ - _Driver= drv; - _DriverIterator= it; -} - -// *************************************************************************** -IVertexProgramDrvInfos::~IVertexProgramDrvInfos () +CVertexProgram::CVertexProgram() { - _Driver->removeVtxPrgDrvInfoPtr (_DriverIterator); + } - // *************************************************************************** -CVertexProgram::CVertexProgram (const char* program) + +CVertexProgram::CVertexProgram(const char *nelvp) { - _Program=program; + CSource *source = new CSource(); + source->Profile = IProgram::nelvp; + source->setSource(nelvp); + addSource(source); } - // *************************************************************************** + CVertexProgram::~CVertexProgram () { - // Must kill the drv mirror of this VB. - _DrvInfo.kill(); + } } // NL3D diff --git a/code/nel/src/3d/vertex_program_parse.cpp b/code/nel/src/3d/vertex_program_parse.cpp index 9b535d551..af3a70b96 100644 --- a/code/nel/src/3d/vertex_program_parse.cpp +++ b/code/nel/src/3d/vertex_program_parse.cpp @@ -885,7 +885,7 @@ bool CVPParser::parseInstruction(CVPInstruction &instr, std::string &errorOutput } // it is not allowed to write to an adress register except for ARL - if (instrStr != 'ARL ') + if (instrStr != NELID("ARL")) { if (instr.Dest.Type == CVPOperand::AddressRegister) { diff --git a/code/nel/src/3d/water_env_map.cpp b/code/nel/src/3d/water_env_map.cpp index 3d2f64a1f..a1b954764 100644 --- a/code/nel/src/3d/water_env_map.cpp +++ b/code/nel/src/3d/water_env_map.cpp @@ -226,9 +226,8 @@ void CWaterEnvMap::doInit() _MaterialPassThru.setZFunc(CMaterial::always); } } - - -static CVertexProgram testMeshVP( +/* +static const char *testMeshVPstr = "!!VP1.0\n\ DP4 o[HPOS].x, c[0], v[0]; \n\ DP4 o[HPOS].y, c[1], v[0]; \n\ @@ -236,14 +235,56 @@ static CVertexProgram testMeshVP( DP4 o[HPOS].w, c[3], v[0]; \n\ MAD o[COL0], v[8], c[4].xxxx, c[4].yyyy; \n\ MOV o[TEX0], v[8]; \n\ - END" -); + END"; + + +class CVertexProgramTestMeshVP : public CVertexProgram +{ +public: + struct CIdx + { + uint ProgramConstant0; + }; + CVertexProgramTestMeshVP() + { + // nelvp + { + CSource *source = new CSource(); + source->Profile = nelvp; + source->DisplayName = "testMeshVP/nelvp"; + source->setSourcePtr(testMeshVPstr); + source->ParamIndices["modelViewProjection"] = 0; + source->ParamIndices["programConstant0"] = 4; + addSource(source); + } + } + virtual ~CVertexProgramTestMeshVP() + { + + } + virtual void buildInfo() + { + m_Idx.ProgramConstant0 = getUniformIndex("programConstant0"); + nlassert(m_Idx.ProgramConstant0 != ~0); + } + inline const CIdx &idx() { return m_Idx; } +private: + CIdx m_Idx; +}; + + +static NLMISC::CSmartPtr testMeshVP; // ******************************************************************************* void CWaterEnvMap::renderTestMesh(IDriver &driver) { + if (!testMeshVP) + { + testMeshVP = new CVertexProgramTestMeshVP(); + } + doInit(); CMaterial testMat; testMat.setLighting(false); @@ -257,18 +298,17 @@ void CWaterEnvMap::renderTestMesh(IDriver &driver) testMat.setZWrite(false); testMat.setZFunc(CMaterial::always); // tmp : test cubemap - driver.activeVertexProgram(&testMeshVP); + driver.activeVertexProgram(testMeshVP); driver.activeVertexBuffer(_TestVB); driver.activeIndexBuffer(_TestIB); - driver.setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); // tmp _MaterialPassThruZTest.setTexture(0, _EnvCubic); - driver.setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); - driver.setConstant(4, 2.f, 1.f, 0.f, 0.f); + driver.setUniformMatrix(IDriver::VertexProgram, testMeshVP->getUniformIndex(CProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); + driver.setUniform2f(IDriver::VertexProgram, testMeshVP->idx().ProgramConstant0, 2.f, 1.f); //driver.renderTriangles(testMat, 0, TEST_VB_NUM_TRIS); driver.renderTriangles(_MaterialPassThruZTest, 0, TEST_VB_NUM_TRIS); driver.activeVertexProgram(NULL); } - +*/ // ******************************************************************************* void CWaterEnvMap::initFlattenVB() { diff --git a/code/nel/src/3d/water_model.cpp b/code/nel/src/3d/water_model.cpp index ddf3d35b2..eb8ceae27 100644 --- a/code/nel/src/3d/water_model.cpp +++ b/code/nel/src/3d/water_model.cpp @@ -61,7 +61,7 @@ void CWaterModel::setupVertexBuffer(CVertexBuffer &vb, uint numWantedVertices, I vb.setNumVertices(0); vb.setName("Water"); vb.setPreferredMemory(CVertexBuffer::AGPPreferred, false); - if (drv->isWaterShaderSupported()) + if (drv->supportWaterShader()) { vb.setVertexFormat(CVertexBuffer::PositionFlag); } @@ -377,7 +377,7 @@ void CWaterModel::traverseRender() #ifndef FORCE_SIMPLE_WATER_RENDER - if (!drv->isWaterShaderSupported()) + if (!drv->supportWaterShader()) #endif { doSimpleRender(drv); @@ -903,11 +903,12 @@ void CWaterModel::setupMaterialNVertexShader(IDriver *drv, CWaterShape *shape, c _WaterMat.setZWrite(true); _WaterMat.setShader(CMaterial::Water); } - const uint cstOffset = 5; // 4 places for the matrix - NLMISC::CVectorH cst[13]; //=========================// // setup Water material // //=========================// + shape->initVertexProgram(); + CVertexProgramWaterVPNoWave *program = shape->_ColorMap ? CWaterShape::_VertexProgramNoWaveDiffuse : CWaterShape::_VertexProgramNoWave; + drv->activeVertexProgram(program); CWaterModel::_WaterMat.setTexture(0, shape->_BumpMap[0]); CWaterModel::_WaterMat.setTexture(1, shape->_BumpMap[1]); CWaterModel::_WaterMat.setTexture(3, shape->_ColorMap); @@ -953,25 +954,21 @@ void CWaterModel::setupMaterialNVertexShader(IDriver *drv, CWaterShape *shape, c { // setup 2x3 matrix for lookup in diffuse map updateDiffuseMapMatrix(); - cst[11].set(_ColorMapMatColumn0.x, _ColorMapMatColumn1.x, 0, _ColorMapMatColumn0.x * obsPos.x + _ColorMapMatColumn1.x * obsPos.y + _ColorMapMatPos.x); - cst[12].set(_ColorMapMatColumn0.y, _ColorMapMatColumn1.y, 0, _ColorMapMatColumn0.y * obsPos.x + _ColorMapMatColumn1.y * obsPos.y + _ColorMapMatPos.y); + drv->setUniform4f(IDriver::VertexProgram, program->idx().DiffuseMapVector0, _ColorMapMatColumn0.x, _ColorMapMatColumn1.x, 0, _ColorMapMatColumn0.x * obsPos.x + _ColorMapMatColumn1.x * obsPos.y + _ColorMapMatPos.x); + drv->setUniform4f(IDriver::VertexProgram, program->idx().DiffuseMapVector1, _ColorMapMatColumn0.y, _ColorMapMatColumn1.y, 0, _ColorMapMatColumn0.y * obsPos.x + _ColorMapMatColumn1.y * obsPos.y + _ColorMapMatPos.y); } - /// set matrix - drv->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); + // set builtins + drv->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity); + drv->setUniformFog(IDriver::VertexProgram, program->getUniformIndex(CProgramIndex::Fog)); // retrieve current time double date = scene->getCurrentTime(); // set bumpmaps pos - cst[6].set(fmodf(obsPos.x * shape->_HeightMapScale[0].x, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[0].x, 1), fmodf(shape->_HeightMapScale[0].y * obsPos.y, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[0].y, 1), 0.f, 1.f); // bump map 0 offset - cst[5].set(shape->_HeightMapScale[0].x, shape->_HeightMapScale[0].y, 0, 0); // bump map 0 scale - cst[8].set(fmodf(shape->_HeightMapScale[1].x * obsPos.x, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[1].x, 1), fmodf(shape->_HeightMapScale[1].y * obsPos.y, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[1].y, 1), 0.f, 1.f); // bump map 1 offset - cst[7].set(shape->_HeightMapScale[1].x, shape->_HeightMapScale[1].y, 0, 0); // bump map 1 scale - cst[9].set(0, 0, obsPos.z - zHeight, 1.f); - cst[10].set(0.5f, 0.5f, 0.f, 1.f); // used to scale reflected ray into the envmap - /// set all our constants in one call - drv->setConstant(cstOffset, sizeof(cst) / sizeof(cst[0]) - cstOffset, (float *) &cst[cstOffset]); - shape->initVertexProgram(); - drv->activeVertexProgram(shape->_ColorMap ? CWaterShape::_VertexProgramNoWaveDiffuse.get() : CWaterShape::_VertexProgramNoWave.get()); - drv->setConstantFog(4); + drv->setUniform4f(IDriver::VertexProgram, program->idx().BumpMap0Offset, fmodf(obsPos.x * shape->_HeightMapScale[0].x, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[0].x, 1), fmodf(shape->_HeightMapScale[0].y * obsPos.y, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[0].y, 1), 0.f, 1.f); // bump map 0 offset + drv->setUniform4f(IDriver::VertexProgram, program->idx().BumpMap0Scale, shape->_HeightMapScale[0].x, shape->_HeightMapScale[0].y, 0, 0); // bump map 0 scale + drv->setUniform4f(IDriver::VertexProgram, program->idx().BumpMap1Offset, fmodf(shape->_HeightMapScale[1].x * obsPos.x, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[1].x, 1), fmodf(shape->_HeightMapScale[1].y * obsPos.y, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[1].y, 1), 0.f, 1.f); // bump map 1 offset + drv->setUniform4f(IDriver::VertexProgram, program->idx().BumpMap1Scale, shape->_HeightMapScale[1].x, shape->_HeightMapScale[1].y, 0, 0); // bump map 1 scale + drv->setUniform4f(IDriver::VertexProgram, program->idx().ObserverHeight, 0, 0, obsPos.z - zHeight, 1.f); + drv->setUniform4f(IDriver::VertexProgram, program->idx().ScaleReflectedRay, 0.5f, 0.5f, 0.f, 1.f); // used to scale reflected ray into the envmap } //================================================ @@ -1363,7 +1360,7 @@ uint CWaterModel::getNumWantedVertices() uint CWaterModel::fillVB(void *datas, uint startTri, IDriver &drv) { H_AUTO( NL3D_Water_Render ); - if (drv.isWaterShaderSupported()) + if (drv.supportWaterShader()) { return fillVBHard(datas, startTri); } @@ -1657,7 +1654,7 @@ void CWaterModel::traverseRender() drv->setupModelMatrix(modelMat); bool isAbove = obsPos.z > getWorldMatrix().getPos().z; CVertexBuffer &vb = renderTrav.Scene->getWaterVB(); - if (drv->isWaterShaderSupported()) + if (drv->supportWaterShader()) { setupMaterialNVertexShader(drv, shape, obsPos, isAbove, zHeight); nlassert(vb.getNumVertices() > 0); diff --git a/code/nel/src/3d/water_shape.cpp b/code/nel/src/3d/water_shape.cpp index 0196294c3..5c675b12b 100644 --- a/code/nel/src/3d/water_shape.cpp +++ b/code/nel/src/3d/water_shape.cpp @@ -81,7 +81,69 @@ DP4 o[TEX3].x, v[0], c[11]; #compute uv for diffuse texture \n\ DP4 o[TEX3].y, v[0], c[12]; \n\ END"; +CVertexProgramWaterVPNoWave::CVertexProgramWaterVPNoWave(bool diffuse) +{ + m_Diffuse = diffuse; + // nelvp + { + CSource *source = new CSource(); + source->Profile = nelvp; + source->DisplayName = "WaterVPNoWave/nelvp"; + source->ParamIndices["modelViewProjection"] = 0; + source->ParamIndices["fog"] = 4; + source->ParamIndices["bumpMap0Scale"] = 5; + source->ParamIndices["bumpMap0Offset"] = 6; + source->ParamIndices["bumpMap1Scale"] = 7; + source->ParamIndices["bumpMap1Offset"] = 8; + source->ParamIndices["observerHeight"] = 9; + source->ParamIndices["scaleReflectedRay"] = 10; + if (diffuse) + { + source->DisplayName += "/diffuse"; + source->ParamIndices["diffuseMapVector0"] = 11; + source->ParamIndices["diffuseMapVector1"] = 12; + source->setSourcePtr(WaterVPNoWaveDiffuse); + } + else + { + source->setSourcePtr(WaterVPNoWave); + } + addSource(source); + } + // glsl330v + { + // TODO_VP_GLSL + // CSource *source = new CSource(); + // source->Profile = glsl330v; + // source->DisplayName = "WaterVPNoWave/glsl330v"; + // if (diffuse) source->DisplayName += "/diffuse"; + // source->setSource... + // addSource(source); + } +} +void CVertexProgramWaterVPNoWave::buildInfo() +{ + m_Idx.BumpMap0Scale = getUniformIndex("bumpMap0Scale"); + nlassert(m_Idx.BumpMap0Scale != ~0); + m_Idx.BumpMap0Offset = getUniformIndex("bumpMap0Offset"); + nlassert(m_Idx.BumpMap0Offset != ~0); + m_Idx.BumpMap1Scale = getUniformIndex("bumpMap1Scale"); + nlassert(m_Idx.BumpMap1Scale != ~0); + m_Idx.BumpMap1Offset = getUniformIndex("bumpMap1Offset"); + nlassert(m_Idx.BumpMap1Offset != ~0); + m_Idx.ObserverHeight = getUniformIndex("observerHeight"); + nlassert(m_Idx.ObserverHeight != ~0); + m_Idx.ScaleReflectedRay = getUniformIndex("scaleReflectedRay"); + nlassert(m_Idx.ScaleReflectedRay != ~0); + if (m_Diffuse) + { + m_Idx.DiffuseMapVector0 = getUniformIndex("diffuseMapVector0"); + nlassert(m_Idx.DiffuseMapVector0 != ~0); + m_Idx.DiffuseMapVector1 = getUniformIndex("diffuseMapVector1"); + nlassert(m_Idx.DiffuseMapVector1 != ~0); + } +} //////////////// // WAVY WATER // @@ -188,19 +250,19 @@ uint32 CWaterShape::_XGridBorder = 4; uint32 CWaterShape::_YGridBorder = 4; uint32 CWaterShape::_MaxGridSize; bool CWaterShape::_GridSizeTouched = true; -std::auto_ptr CWaterShape::_VertexProgramBump1; -std::auto_ptr CWaterShape::_VertexProgramBump2; -std::auto_ptr CWaterShape::_VertexProgramBump1Diffuse; -std::auto_ptr CWaterShape::_VertexProgramBump2Diffuse; -std::auto_ptr CWaterShape::_VertexProgramNoBump; -std::auto_ptr CWaterShape::_VertexProgramNoBumpDiffuse; +/*NLMISC::CSmartPtr CWaterShape::_VertexProgramBump1; +NLMISC::CSmartPtr CWaterShape::_VertexProgramBump2; +NLMISC::CSmartPtr CWaterShape::_VertexProgramBump1Diffuse; +NLMISC::CSmartPtr CWaterShape::_VertexProgramBump2Diffuse; +NLMISC::CSmartPtr CWaterShape::_VertexProgramNoBump; +NLMISC::CSmartPtr CWaterShape::_VertexProgramNoBumpDiffuse;*/ // water with no waves -std::auto_ptr CWaterShape::_VertexProgramNoWave; -std::auto_ptr CWaterShape::_VertexProgramNoWaveDiffuse; +NLMISC::CSmartPtr CWaterShape::_VertexProgramNoWave; +NLMISC::CSmartPtr CWaterShape::_VertexProgramNoWaveDiffuse; /** Build a vertex program for water depending on requirements - */ + *//* static CVertexProgram *BuildWaterVP(bool diffuseMap, bool bumpMap, bool use2BumpMap) { std::string vp = WaterVPStartCode; @@ -224,7 +286,7 @@ static CVertexProgram *BuildWaterVP(bool diffuseMap, bool bumpMap, bool use2Bump vp += "\nEND"; return new CVertexProgram(vp.c_str()); } - +*/ //============================================ @@ -321,17 +383,17 @@ void CWaterShape::initVertexProgram() if (!created) { // waves - _VertexProgramBump1 = std::auto_ptr(BuildWaterVP(false, true, false)); - _VertexProgramBump2 = std::auto_ptr(BuildWaterVP(false, true, true)); + /*_VertexProgramBump1 = BuildWaterVP(false, true, false); + _VertexProgramBump2 = BuildWaterVP(false, true, true); - _VertexProgramBump1Diffuse = std::auto_ptr(BuildWaterVP(true, true, false)); - _VertexProgramBump2Diffuse = std::auto_ptr(BuildWaterVP(true, true, true)); + _VertexProgramBump1Diffuse = BuildWaterVP(true, true, false); + _VertexProgramBump2Diffuse = BuildWaterVP(true, true, true); - _VertexProgramNoBump = std::auto_ptr(BuildWaterVP(false, false, false)); - _VertexProgramNoBumpDiffuse = std::auto_ptr(BuildWaterVP(true, false, false)); + _VertexProgramNoBump = BuildWaterVP(false, false, false); + _VertexProgramNoBumpDiffuse = BuildWaterVP(true, false, false);*/ // no waves - _VertexProgramNoWave.reset(new CVertexProgram(WaterVPNoWave)); - _VertexProgramNoWaveDiffuse.reset(new CVertexProgram(WaterVPNoWaveDiffuse)); + _VertexProgramNoWave = new CVertexProgramWaterVPNoWave(false); + _VertexProgramNoWaveDiffuse = new CVertexProgramWaterVPNoWave(true); created = true; } } @@ -372,7 +434,7 @@ void CWaterShape::flushTextures (IDriver &driver, uint selectedTexture) /* if ( - (driver.supportTextureShaders() && driver.isTextureAddrModeSupported(CMaterial::OffsetTexture)) + (driver.supportTextureShaders() && driver.supportTextureAddrMode(CMaterial::OffsetTexture)) || driver.supportEMBM() ) { diff --git a/code/nel/src/3d/zone.cpp b/code/nel/src/3d/zone.cpp index 4acca80f5..c601f0fa4 100644 --- a/code/nel/src/3d/zone.cpp +++ b/code/nel/src/3d/zone.cpp @@ -458,7 +458,7 @@ void CZone::serial(NLMISC::IStream &f) throw EOlderStream(f); } - f.serialCheck((uint32)'ENOZ'); + f.serialCheck(NELID("ENOZ")); f.xmlSerial (ZoneId, "ZONE_ID"); f.xmlSerial (ZoneBB, "BB"); diff --git a/code/nel/src/gui/CMakeLists.txt b/code/nel/src/gui/CMakeLists.txt index e6a943594..e3d501e23 100644 --- a/code/nel/src/gui/CMakeLists.txt +++ b/code/nel/src/gui/CMakeLists.txt @@ -6,26 +6,15 @@ SOURCE_GROUP("src" FILES ${SRC}) NL_TARGET_LIB(nelgui ${SRC} ${HEADERS}) +INCLUDE_DIRECTORIES(${LUA_INCLUDE_DIR} ${LUABIND_INCLUDE_DIR} ${LIBWWW_INCLUDE_DIR}) + +TARGET_LINK_LIBRARIES(nelgui nelmisc nel3d ${LUA_LIBRARIES} ${LUABIND_LIBRARIES} ${LIBXML2_LIBRARIES} ${LIBWWW_LIBRARIES} ${CURL_LIBRARIES}) SET_TARGET_PROPERTIES(nelgui PROPERTIES LINK_INTERFACE_LIBRARIES "") NL_DEFAULT_PROPS(nelgui "NeL, Library: NeL GUI") NL_ADD_RUNTIME_FLAGS(nelgui) -INCLUDE_DIRECTORIES(${LUA_INCLUDE_DIR} ${LUABIND_INCLUDE_DIR} ${LIBWWW_INCLUDE_DIR}) - NL_ADD_LIB_SUFFIX(nelgui) -#MESSAGE( "libww libs: ${LIBWWW_LIBRARIES}" ) - -TARGET_LINK_LIBRARIES( nelgui - nelmisc - nel3d - ${LUA_LIBRARIES} - ${LUABIND_LIBRARIES} - ${LIBXML2_LIBRARIES} - ${LIBWWW_LIBRARIES} - ${CURL_LIBRARIES} - ) - ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} ${CURL_DEFINITIONS} ${LUABIND_DEFINITIONS}) IF(WITH_PCH) @@ -33,5 +22,5 @@ IF(WITH_PCH) ENDIF(WITH_PCH) IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) - INSTALL(TARGETS nelgui LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries) + INSTALL(TARGETS nelgui LIBRARY DESTINATION ${NL_LIB_PREFIX} ARCHIVE DESTINATION ${NL_LIB_PREFIX} COMPONENT libraries) ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) diff --git a/code/nel/src/gui/ctrl_base_button.cpp b/code/nel/src/gui/ctrl_base_button.cpp index 8c74e3bfc..4a0c53cf4 100644 --- a/code/nel/src/gui/ctrl_base_button.cpp +++ b/code/nel/src/gui/ctrl_base_button.cpp @@ -549,27 +549,27 @@ namespace NLGUI if( editorMode ) { prop = (char*) xmlGetProp( cur, BAD_CAST "onover" ); - if( prop != NULL ) + if (prop) mapAHString( "onover", std::string( (const char*)prop ) ); prop = (char*) xmlGetProp( cur, BAD_CAST "onclick_l" ); - if( prop != NULL ) + if (prop) mapAHString( "onclick_l", std::string( (const char*)prop ) ); prop = (char*) xmlGetProp( cur, BAD_CAST "ondblclick_l" ); - if( prop != NULL ) + if (prop) mapAHString( "ondblclick_l", std::string( (const char*)prop ) ); prop = (char*) xmlGetProp( cur, BAD_CAST "onclick_r" ); - if( prop != NULL ) + if (prop) mapAHString( "onclick_r", std::string( (const char*)prop ) ); prop = (char*) xmlGetProp( cur, BAD_CAST "onlongclick_l" ); - if( prop != NULL ) + if (prop) mapAHString( "onlongclick_l", std::string( (const char*)prop ) ); prop = (char*) xmlGetProp( cur, BAD_CAST "onclock_tick" ); - if( prop != NULL ) + if (prop) mapAHString( "onclock_tick", std::string( (const char*)prop ) ); } diff --git a/code/nel/src/gui/group_container.cpp b/code/nel/src/gui/group_container.cpp index 9cb31deab..c3a7834c5 100644 --- a/code/nel/src/gui/group_container.cpp +++ b/code/nel/src/gui/group_container.cpp @@ -2233,35 +2233,35 @@ namespace NLGUI if( editorMode ) { ptr = xmlGetProp( cur, BAD_CAST "on_open" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_open", std::string( (const char*)ptr ) ); ptr = xmlGetProp( cur, BAD_CAST "on_close" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_close", std::string( (const char*)ptr ) ); ptr = xmlGetProp( cur, BAD_CAST "on_close_button" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_close_button", std::string( (const char*)ptr ) ); ptr = xmlGetProp( cur, BAD_CAST "on_move" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_move", std::string( (const char*)ptr ) ); ptr = xmlGetProp( cur, BAD_CAST "on_deactive_check" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_deactive_check", std::string( (const char*)ptr ) ); ptr = xmlGetProp( cur, BAD_CAST "on_resize" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_resize", std::string( (const char*)ptr ) ); ptr = xmlGetProp( cur, BAD_CAST "on_alpha_settings_changed" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_alpha_settings_changed", std::string( (const char*)ptr ) ); ptr = xmlGetProp( cur, BAD_CAST "on_begin_move" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_begin_move", std::string( (const char*)ptr ) ); } diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp index 4e8eb3e36..5c2f3bf1d 100644 --- a/code/nel/src/gui/group_editbox.cpp +++ b/code/nel/src/gui/group_editbox.cpp @@ -540,7 +540,7 @@ namespace NLGUI if( editorMode ) { prop = (char*) xmlGetProp( cur, BAD_CAST "onenter" ); - if( prop != NULL ) + if (prop) mapAHString( "onenter", std::string( (const char*)prop ) ); } diff --git a/code/nel/src/gui/group_modal.cpp b/code/nel/src/gui/group_modal.cpp index 654a372f0..fb4c6d129 100644 --- a/code/nel/src/gui/group_modal.cpp +++ b/code/nel/src/gui/group_modal.cpp @@ -244,29 +244,29 @@ namespace NLGUI // read modal option CXMLAutoPtr prop; prop = xmlGetProp (cur, (xmlChar*)"mouse_pos"); - if ( prop ) SpawnOnMousePos= convertBool(prop); + if (prop) SpawnOnMousePos= convertBool(prop); prop = xmlGetProp (cur, (xmlChar*)"exit_click_out"); - if ( prop ) ExitClickOut= convertBool(prop); + if (prop) ExitClickOut= convertBool(prop); prop = xmlGetProp (cur, (xmlChar*)"exit_click_l"); - if ( prop ) ExitClickL= convertBool(prop); + if (prop) ExitClickL= convertBool(prop); prop = xmlGetProp (cur, (xmlChar*)"exit_click_r"); - if ( prop ) ExitClickR= convertBool(prop); + if (prop) ExitClickR= convertBool(prop); prop = xmlGetProp (cur, (xmlChar*)"exit_click_b"); - if ( prop ) ExitClickR= ExitClickL= convertBool(prop); + if (prop) ExitClickR= ExitClickL= convertBool(prop); prop = xmlGetProp (cur, (xmlChar*)"force_inside_screen"); - if ( prop ) ForceInsideScreen= convertBool(prop); + if (prop) ForceInsideScreen= convertBool(prop); prop = xmlGetProp (cur, (xmlChar*)"category"); - if ( prop ) Category= (const char *) prop; + if (prop) Category= (const char *) prop; prop = xmlGetProp (cur, (xmlChar*)"onclick_out"); - if ( prop ) OnClickOut = (const char *) prop; + if (prop) OnClickOut = (const char *) prop; prop = xmlGetProp (cur, (xmlChar*)"onclick_out_params"); - if ( prop ) OnClickOutParams = (const char *) prop; + if (prop) OnClickOutParams = (const char *) prop; prop = xmlGetProp (cur, (xmlChar*)"onpostclick_out"); - if ( prop ) OnPostClickOut = (const char *) prop; + if (prop) OnPostClickOut = (const char *) prop; prop = xmlGetProp (cur, (xmlChar*)"onpostclick_out_params"); - if ( prop ) OnPostClickOutParams = (const char *) prop; + if (prop) OnPostClickOutParams = (const char *) prop; prop = xmlGetProp (cur, (xmlChar*)"exit_key_pushed"); - if ( prop ) ExitKeyPushed= convertBool(prop); + if (prop) ExitKeyPushed= convertBool(prop); // Force parent hotspot for spawn on mouse if(SpawnOnMousePos) diff --git a/code/nel/src/gui/group_wheel.cpp b/code/nel/src/gui/group_wheel.cpp index 59172382e..6f4c96484 100644 --- a/code/nel/src/gui/group_wheel.cpp +++ b/code/nel/src/gui/group_wheel.cpp @@ -119,11 +119,11 @@ namespace NLGUI if( editorMode ) { CXMLAutoPtr ptr( (char*) xmlGetProp( cur, BAD_CAST "on_wheel_up" ) ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_wheel_up", std::string( (const char*)ptr ) ); ptr = (char*) xmlGetProp( cur, BAD_CAST "on_wheel_down" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_wheel_down", std::string( (const char*)ptr ) ); } diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 4e8919e5c..b2de26527 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -349,27 +349,27 @@ namespace NLGUI if( editorMode ) { ptr = (char*) xmlGetProp( cur, BAD_CAST "on_active" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_active", std::string( (const char*)ptr ) ); ptr = (char*) xmlGetProp( cur, BAD_CAST "on_deactive" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_deactive", std::string( (const char*)ptr ) ); ptr = (char*) xmlGetProp( cur, BAD_CAST "group_onclick_r" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "group_onclick_r", std::string( (const char*)ptr ) ); ptr = (char*) xmlGetProp( cur, BAD_CAST "group_onclick_l" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "group_onclick_l", std::string( (const char*)ptr ) ); ptr = (char*) xmlGetProp( cur, BAD_CAST "on_enter" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_enter", std::string( (const char*)ptr ) ); ptr = (char*) xmlGetProp( cur, BAD_CAST "on_escape" ); - if( ptr != NULL ) + if( ptr ) mapAHString( "on_escape", std::string( (const char*)ptr ) ); } diff --git a/code/nel/src/gui/interface_parser.cpp b/code/nel/src/gui/interface_parser.cpp index da8bd1e52..01e47bb80 100644 --- a/code/nel/src/gui/interface_parser.cpp +++ b/code/nel/src/gui/interface_parser.cpp @@ -41,7 +41,7 @@ #ifdef LUA_NEVRAX_VERSION #include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger #endif -const uint32 UI_CACHE_SERIAL_CHECK = (uint32) 'IUG_'; +const uint32 UI_CACHE_SERIAL_CHECK = NELID("IUG_"); using namespace NLMISC; using namespace std; @@ -1001,7 +1001,7 @@ namespace NLGUI ptr = (char*) xmlGetProp (cur, (xmlChar*)"target"); std::string target; - if( ptr != NULL ) + if( ptr ) { target = std::string( (const char*)ptr ); if( !editorMode ) @@ -1136,17 +1136,17 @@ namespace NLGUI VariableData data; ptr = xmlGetProp( cur, BAD_CAST "entry" ); - if( ptr != NULL ) + if( ptr ) data.entry = std::string( (const char*)ptr ); data.type = type; ptr = xmlGetProp( cur, BAD_CAST "value" ); - if( ptr != NULL ) + if( ptr ) data.value = std::string( (const char*)ptr ); ptr = xmlGetProp( cur, BAD_CAST "size" ); - if( ptr != NULL ) + if( ptr ) fromString( std::string( (const char*)ptr ), data.size ); variableCache[ data.entry ] = data; diff --git a/code/nel/src/ligo/ligo_material.cpp b/code/nel/src/ligo/ligo_material.cpp index 643629648..c5e7541a3 100644 --- a/code/nel/src/ligo/ligo_material.cpp +++ b/code/nel/src/ligo/ligo_material.cpp @@ -80,7 +80,7 @@ void CMaterial::serial (NLMISC::IStream &s) s.xmlPush ("LIGO_MATERIAL"); // Serial the header - s.serialCheck ((uint32)'TMOL'); + s.serialCheck (NELID("TMOL")); // Serial the version /*sint ver =*/ s.serialVersion (0); diff --git a/code/nel/src/ligo/transition.cpp b/code/nel/src/ligo/transition.cpp index b13c4f566..ee6921c78 100644 --- a/code/nel/src/ligo/transition.cpp +++ b/code/nel/src/ligo/transition.cpp @@ -199,7 +199,7 @@ void CTransition::serial (NLMISC::IStream &s) s.xmlPush ("LIGO_TRANSITION"); // Serial the header - s.serialCheck ((uint32)'STGL'); + s.serialCheck (NELID("STGL")); // Serial the version /*sint ver =*/ s.serialVersion (0); diff --git a/code/nel/src/ligo/zone_region.cpp b/code/nel/src/ligo/zone_region.cpp index ad65aec8e..9926d3757 100644 --- a/code/nel/src/ligo/zone_region.cpp +++ b/code/nel/src/ligo/zone_region.cpp @@ -153,7 +153,7 @@ void CZoneRegion::serial (NLMISC::IStream &f) f.xmlPush ("LAND"); sint32 version = f.serialVersion (1); - f.serialCheck ((uint32)'DNAL'); + f.serialCheck (NELID("DNAL")); f.xmlSerial (_MinX, "MIN_X"); f.xmlSerial (_MinY, "MIN_Y"); diff --git a/code/nel/src/misc/p_thread.cpp b/code/nel/src/misc/p_thread.cpp index e4deab4ca..a24029b3c 100644 --- a/code/nel/src/misc/p_thread.cpp +++ b/code/nel/src/misc/p_thread.cpp @@ -17,6 +17,9 @@ #include "stdmisc.h" +#include +#include + #ifdef NL_OS_UNIX #include "nel/misc/p_thread.h" diff --git a/code/nel/src/misc/system_info.cpp b/code/nel/src/misc/system_info.cpp index 7ef96ec58..1fa91db6c 100644 --- a/code/nel/src/misc/system_info.cpp +++ b/code/nel/src/misc/system_info.cpp @@ -231,7 +231,14 @@ string CSystemInfo::getOS() } else if ( osvi.dwMajorVersion == 6 ) { - if ( osvi.dwMinorVersion == 1 ) + if ( osvi.dwMinorVersion == 2 ) + { + if( osvi.wProductType == VER_NT_WORKSTATION ) + OSString += " Windows 8"; + else + OSString += " Windows Server 2012"; + } + else if ( osvi.dwMinorVersion == 1 ) { if( osvi.wProductType == VER_NT_WORKSTATION ) OSString += " Windows 7"; diff --git a/code/nel/src/pacs/primitive_block_pacs.cpp b/code/nel/src/pacs/primitive_block_pacs.cpp index 0681d2eea..1ee0615ea 100644 --- a/code/nel/src/pacs/primitive_block_pacs.cpp +++ b/code/nel/src/pacs/primitive_block_pacs.cpp @@ -16,6 +16,7 @@ #include "stdpacs.h" #include "nel/misc/i_xml.h" +#include "nel/misc/stream.h" #include "nel/pacs/primitive_block.h" @@ -85,7 +86,7 @@ void CPrimitiveBlock::serial (NLMISC::IStream &s) s.xmlPush ("PRIMITIVE_BLOCK"); // Serial checks - s.serialCheck ((uint32)'KBRP'); + s.serialCheck (NELID("KBRP")); // Serial the version (void)s.serialVersion (0); diff --git a/code/nel/tools/3d/object_viewer/object_viewer.cpp b/code/nel/tools/3d/object_viewer/object_viewer.cpp index bc9949079..ff530e007 100644 --- a/code/nel/tools/3d/object_viewer/object_viewer.cpp +++ b/code/nel/tools/3d/object_viewer/object_viewer.cpp @@ -1711,8 +1711,8 @@ void CObjectViewer::serial (NLMISC::IStream& f) { // version 4: include particle workspace infos // serial "OBJV_CFG" - f.serialCheck ((uint32)'VJBO'); - f.serialCheck ((uint32)'GFC_'); + f.serialCheck (NELID("VJBO")); + f.serialCheck (NELID("GFC_")); // serial the version int ver=f.serialVersion (4); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/expandable_headerview.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/expandable_headerview.h index f7f26eafc..4071b4637 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/expandable_headerview.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/georges_editor/expandable_headerview.h @@ -15,35 +15,35 @@ // along with this program. If not, see . #ifndef EXPANDABLE_HEADERVIEW_H -#define EXPANDABLE_HEADERVIEW_H - -// Qt includes -#include - -namespace GeorgesQt -{ - class ExpandableHeaderView : public QHeaderView - { - Q_OBJECT - public: - ExpandableHeaderView(Qt::Orientation orientation, QWidget * parent = 0); - - bool* expanded() { return &m_expanded; } - - protected: - void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const; - bool isPointInDecoration(int section, QPoint pos)const; - void mousePressEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - - private: - bool m_expanded; - bool m_inDecoration; - -Q_SIGNALS: - void headerClicked(int); - }; - -} /* namespace NLQT */ - -#endif // EXPANDABLE_HEADERVIEW_H +#define EXPANDABLE_HEADERVIEW_H + +// Qt includes +#include + +namespace GeorgesQt +{ + class ExpandableHeaderView : public QHeaderView + { + Q_OBJECT + public: + ExpandableHeaderView(Qt::Orientation orientation, QWidget * parent = 0); + + bool* expanded() { return &m_expanded; } + + protected: + void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const; + bool isPointInDecoration(int section, QPoint pos)const; + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + + private: + bool m_expanded; + bool m_inDecoration; + +Q_SIGNALS: + void headerClicked(int); + }; + +} /* namespace NLQT */ + +#endif // EXPANDABLE_HEADERVIEW_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/CMakeLists.txt index 409005a6a..a9083613e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/CMakeLists.txt @@ -1,7 +1,8 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${LIBXML2_INCLUDE_DIR} - ${QT_INCLUDES}) + ${QT_INCLUDES} + ${LUA_INCLUDE_DIR}) FILE(GLOB SRC *.cpp *.h) @@ -71,6 +72,7 @@ TARGET_LINK_LIBRARIES( nelgui ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY} + ${LIBXML2_LIBRARIES} qt_property_browser ) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.cpp index 5a8c64f93..0f86ab90c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.cpp @@ -1,191 +1,191 @@ -// Object Viewer Qt - Log Plugin - MMORPG Framework -// Copyright (C) 2011 Adrian Jaekel -// -// 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 . - -// Project includes -#include "log_plugin.h" -#include "log_settings_page.h" -#include "qt_displayer.h" - -#include "../core/icore.h" -#include "../core/core_constants.h" -#include "../core/menu_manager.h" -#include "../../extension_system/iplugin_spec.h" - -// Qt includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// NeL includes -#include - -namespace Plugin -{ - - CLogPlugin::CLogPlugin(QWidget *parent): QDockWidget(parent) - { - m_ui.setupUi(this); - } - - CLogPlugin::~CLogPlugin() - { - Q_FOREACH(QObject *obj, m_autoReleaseObjects) - { - m_plugMan->removeObject(obj); - } - qDeleteAll(m_autoReleaseObjects); - m_autoReleaseObjects.clear(); - - NLMISC::ErrorLog->removeDisplayer(m_displayer); - NLMISC::WarningLog->removeDisplayer(m_displayer); - NLMISC::DebugLog->removeDisplayer(m_displayer); - NLMISC::AssertLog->removeDisplayer(m_displayer); - NLMISC::InfoLog->removeDisplayer(m_displayer); - delete m_displayer; - } - - bool CLogPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) - { - Q_UNUSED(errorString); - m_plugMan = pluginManager; - m_logSettingsPage = new CLogSettingsPage(this, this); - addAutoReleasedObject(m_logSettingsPage); - return true; - } - - void CLogPlugin::extensionsInitialized() - { - setDisplayers(); - - Core::ICore *core = Core::ICore::instance(); - Core::MenuManager *menuManager = core->menuManager(); - QMenu *viewMenu = menuManager->menu(Core::Constants::M_VIEW); - - QMainWindow *wnd = Core::ICore::instance()->mainWindow(); - wnd->addDockWidget(Qt::RightDockWidgetArea, this); - hide(); - - viewMenu->addAction(this->toggleViewAction()); - } - - void CLogPlugin::setNelContext(NLMISC::INelContext *nelContext) - { -#ifdef NL_OS_WINDOWS - // Ensure that a context doesn't exist yet. - // This only applies to platforms without PIC, e.g. Windows. - nlassert(!NLMISC::INelContext::isContextInitialised()); -#endif // fdef NL_OS_WINDOWS^M - m_libContext = new NLMISC::CLibraryContext(*nelContext); - - m_displayer = new NLQT::CQtDisplayer(m_ui.plainTextEdit); - - } - - QString CLogPlugin::name() const - { - return "LogPlugin"; - } - - QString CLogPlugin::version() const - { - return "1.1"; - } - - QString CLogPlugin::vendor() const - { - return "aquiles"; - } - - QString CLogPlugin::description() const - { - return tr("DockWidget to display all log messages from NeL."); - } - - QStringList CLogPlugin::dependencies() const - { - QStringList list; - list.append(Core::Constants::OVQT_CORE_PLUGIN); - return list; - } - - void CLogPlugin::addAutoReleasedObject(QObject *obj) - { - m_plugMan->addObject(obj); - m_autoReleaseObjects.prepend(obj); - } - - void CLogPlugin::setDisplayers() - { - QSettings *settings = Core::ICore::instance()->settings(); - - settings->beginGroup(Core::Constants::LOG_SECTION); +// Object Viewer Qt - Log Plugin - MMORPG Framework +// Copyright (C) 2011 Adrian Jaekel +// +// 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 . + +// Project includes +#include "log_plugin.h" +#include "log_settings_page.h" +#include "qt_displayer.h" + +#include "../core/icore.h" +#include "../core/core_constants.h" +#include "../core/menu_manager.h" +#include "../../extension_system/iplugin_spec.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// NeL includes +#include + +namespace Plugin +{ + + CLogPlugin::CLogPlugin(QWidget *parent): QDockWidget(parent) + { + m_ui.setupUi(this); + } + + CLogPlugin::~CLogPlugin() + { + Q_FOREACH(QObject *obj, m_autoReleaseObjects) + { + m_plugMan->removeObject(obj); + } + qDeleteAll(m_autoReleaseObjects); + m_autoReleaseObjects.clear(); + + NLMISC::ErrorLog->removeDisplayer(m_displayer); + NLMISC::WarningLog->removeDisplayer(m_displayer); + NLMISC::DebugLog->removeDisplayer(m_displayer); + NLMISC::AssertLog->removeDisplayer(m_displayer); + NLMISC::InfoLog->removeDisplayer(m_displayer); + delete m_displayer; + } + + bool CLogPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) + { + Q_UNUSED(errorString); + m_plugMan = pluginManager; + m_logSettingsPage = new CLogSettingsPage(this, this); + addAutoReleasedObject(m_logSettingsPage); + return true; + } + + void CLogPlugin::extensionsInitialized() + { + setDisplayers(); + + Core::ICore *core = Core::ICore::instance(); + Core::MenuManager *menuManager = core->menuManager(); + QMenu *viewMenu = menuManager->menu(Core::Constants::M_VIEW); + + QMainWindow *wnd = Core::ICore::instance()->mainWindow(); + wnd->addDockWidget(Qt::RightDockWidgetArea, this); + hide(); + + viewMenu->addAction(this->toggleViewAction()); + } + + void CLogPlugin::setNelContext(NLMISC::INelContext *nelContext) + { +#ifdef NL_OS_WINDOWS + // Ensure that a context doesn't exist yet. + // This only applies to platforms without PIC, e.g. Windows. + nlassert(!NLMISC::INelContext::isContextInitialised()); +#endif // fdef NL_OS_WINDOWS^M + m_libContext = new NLMISC::CLibraryContext(*nelContext); + + m_displayer = new NLQT::CQtDisplayer(m_ui.plainTextEdit); + + } + + QString CLogPlugin::name() const + { + return "LogPlugin"; + } + + QString CLogPlugin::version() const + { + return "1.1"; + } + + QString CLogPlugin::vendor() const + { + return "aquiles"; + } + + QString CLogPlugin::description() const + { + return tr("DockWidget to display all log messages from NeL."); + } + + QStringList CLogPlugin::dependencies() const + { + QStringList list; + list.append(Core::Constants::OVQT_CORE_PLUGIN); + return list; + } + + void CLogPlugin::addAutoReleasedObject(QObject *obj) + { + m_plugMan->addObject(obj); + m_autoReleaseObjects.prepend(obj); + } + + void CLogPlugin::setDisplayers() + { + QSettings *settings = Core::ICore::instance()->settings(); + + settings->beginGroup(Core::Constants::LOG_SECTION); bool error = settings->value(Core::Constants::LOG_ERROR, true).toBool(); bool warning = settings->value(Core::Constants::LOG_WARNING, true).toBool(); bool debug = settings->value(Core::Constants::LOG_DEBUG, true).toBool(); bool assert = settings->value(Core::Constants::LOG_ASSERT, true).toBool(); - bool info = settings->value(Core::Constants::LOG_INFO, true).toBool(); - settings->endGroup(); - - if (error) { - if (!NLMISC::ErrorLog->attached(m_displayer)) - NLMISC::ErrorLog->addDisplayer(m_displayer); - } else { - if (m_displayer) { - NLMISC::ErrorLog->removeDisplayer(m_displayer); - } - } - if (warning) { - if (!NLMISC::WarningLog->attached(m_displayer)) - NLMISC::WarningLog->addDisplayer(m_displayer); - } else { - if (m_displayer) { - NLMISC::WarningLog->removeDisplayer(m_displayer); - } - } - if (debug) { - if (!NLMISC::DebugLog->attached(m_displayer)) - NLMISC::DebugLog->addDisplayer(m_displayer); - } else { - if (m_displayer) { - NLMISC::DebugLog->removeDisplayer(m_displayer); - } - } - if (assert) { - if (!NLMISC::AssertLog->attached(m_displayer)) - NLMISC::AssertLog->addDisplayer(m_displayer); - } else { - if (m_displayer) { - NLMISC::AssertLog->removeDisplayer(m_displayer); - } - } - if (info) { - if (!NLMISC::InfoLog->attached(m_displayer)) - NLMISC::InfoLog->addDisplayer(m_displayer); - } else { - if (m_displayer) { - NLMISC::InfoLog->removeDisplayer(m_displayer); - } - } - } -} -Q_EXPORT_PLUGIN(Plugin::CLogPlugin) + bool info = settings->value(Core::Constants::LOG_INFO, true).toBool(); + settings->endGroup(); + + if (error) { + if (!NLMISC::ErrorLog->attached(m_displayer)) + NLMISC::ErrorLog->addDisplayer(m_displayer); + } else { + if (m_displayer) { + NLMISC::ErrorLog->removeDisplayer(m_displayer); + } + } + if (warning) { + if (!NLMISC::WarningLog->attached(m_displayer)) + NLMISC::WarningLog->addDisplayer(m_displayer); + } else { + if (m_displayer) { + NLMISC::WarningLog->removeDisplayer(m_displayer); + } + } + if (debug) { + if (!NLMISC::DebugLog->attached(m_displayer)) + NLMISC::DebugLog->addDisplayer(m_displayer); + } else { + if (m_displayer) { + NLMISC::DebugLog->removeDisplayer(m_displayer); + } + } + if (assert) { + if (!NLMISC::AssertLog->attached(m_displayer)) + NLMISC::AssertLog->addDisplayer(m_displayer); + } else { + if (m_displayer) { + NLMISC::AssertLog->removeDisplayer(m_displayer); + } + } + if (info) { + if (!NLMISC::InfoLog->attached(m_displayer)) + NLMISC::InfoLog->addDisplayer(m_displayer); + } else { + if (m_displayer) { + NLMISC::InfoLog->removeDisplayer(m_displayer); + } + } + } +} +Q_EXPORT_PLUGIN(Plugin::CLogPlugin) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.h index 6a2d78f79..2221195a8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_plugin.h @@ -1,33 +1,33 @@ -/* -Log Plugin Qt -Copyright (C) 2011 Adrian Jaekel - -This program 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 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 General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - +/* +Log Plugin Qt +Copyright (C) 2011 Adrian Jaekel + +This program 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 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + */ #ifndef LOG_PLUGIN_H #define LOG_PLUGIN_H -// Project includes +// Project includes #include "ui_log_form.h" #include "../../extension_system/iplugin.h" // NeL includes #include "nel/misc/app_context.h" -// Qt includes +// Qt includes #include namespace NLMISC @@ -54,7 +54,7 @@ namespace Plugin Q_OBJECT Q_INTERFACES(ExtensionSystem::IPlugin) public: - CLogPlugin(QWidget *parent = 0); + CLogPlugin(QWidget *parent = 0); ~CLogPlugin(); bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); @@ -63,26 +63,26 @@ namespace Plugin void setNelContext(NLMISC::INelContext *nelContext); NLQT::CQtDisplayer* displayer() { return m_displayer; } - QString name() const; - QString version() const; - QString vendor() const; + QString name() const; + QString version() const; + QString vendor() const; QString description() const; - QStringList dependencies() const; - - void addAutoReleasedObject(QObject *obj); - - void setDisplayers(); - - protected: - NLMISC::CLibraryContext *m_libContext; + QStringList dependencies() const; + + void addAutoReleasedObject(QObject *obj); + + void setDisplayers(); + + protected: + NLMISC::CLibraryContext *m_libContext; private: ExtensionSystem::IPluginManager *m_plugMan; QList m_autoReleaseObjects; CLogSettingsPage *m_logSettingsPage; - Ui::CLogPlugin m_ui; - + Ui::CLogPlugin m_ui; + NLQT::CQtDisplayer *m_displayer; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.cpp index 3aba359a5..4b3fa1ebb 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/log/log_settings_page.cpp @@ -1,133 +1,133 @@ -// Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// Copyright (C) 2011 Adrian Jaekel -// -// 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 . - -// Project includes -#include "log_settings_page.h" -#include "log_plugin.h" -#include "../core/core_constants.h" -#include "../core/icore.h" -#include "../../extension_system/plugin_manager.h" - -// NeL includes - -// Qt includes -#include -#include - +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Adrian Jaekel +// +// 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 . + +// Project includes +#include "log_settings_page.h" +#include "log_plugin.h" +#include "../core/core_constants.h" +#include "../core/icore.h" +#include "../../extension_system/plugin_manager.h" + +// NeL includes + +// Qt includes +#include +#include + namespace ExtensionSystem { - class IPluginManager; -} - -namespace Plugin -{ - - class CLogPlugin; - - CLogSettingsPage::CLogSettingsPage(CLogPlugin *logPlugin, QObject *parent) - : IOptionsPage(parent), - m_logPlugin(logPlugin), - m_currentPage(NULL), + class IPluginManager; +} + +namespace Plugin +{ + + class CLogPlugin; + + CLogSettingsPage::CLogSettingsPage(CLogPlugin *logPlugin, QObject *parent) + : IOptionsPage(parent), + m_logPlugin(logPlugin), + m_currentPage(NULL), m_error(true), m_warning(true), m_debug(true), m_assert(true), - m_info(true) - { - } - - QString CLogSettingsPage::id() const - { - return QLatin1String("log"); - } - - QString CLogSettingsPage::trName() const - { - return tr("Log"); - } - - QString CLogSettingsPage::category() const - { - return QLatin1String(Core::Constants::SETTINGS_CATEGORY_GENERAL); - } - - QString CLogSettingsPage::trCategory() const - { - return tr(Core::Constants::SETTINGS_TR_CATEGORY_GENERAL); - } - - QIcon CLogSettingsPage::categoryIcon() const - { - return QIcon(); - } - - QWidget *CLogSettingsPage::createPage(QWidget *parent) - { - m_currentPage = new QWidget(parent); - m_ui.setupUi(m_currentPage); - - readSettings(); - m_ui.errorCheck->setChecked(m_error); - m_ui.warningCheck->setChecked(m_warning); - m_ui.debugCheck->setChecked(m_debug); - m_ui.assertCheck->setChecked(m_assert); - m_ui.infoCheck->setChecked(m_info); - - return m_currentPage; - } - - void CLogSettingsPage::apply() - { - m_error = m_ui.errorCheck->isChecked(); - m_warning = m_ui.warningCheck->isChecked(); - m_debug = m_ui.debugCheck->isChecked(); - m_assert = m_ui.assertCheck->isChecked(); - m_info = m_ui.infoCheck->isChecked(); - - writeSettings(); - m_logPlugin->setDisplayers(); - } - - void CLogSettingsPage::readSettings() - { - QSettings *settings = Core::ICore::instance()->settings(); - - settings->beginGroup(Core::Constants::LOG_SECTION); + m_info(true) + { + } + + QString CLogSettingsPage::id() const + { + return QLatin1String("log"); + } + + QString CLogSettingsPage::trName() const + { + return tr("Log"); + } + + QString CLogSettingsPage::category() const + { + return QLatin1String(Core::Constants::SETTINGS_CATEGORY_GENERAL); + } + + QString CLogSettingsPage::trCategory() const + { + return tr(Core::Constants::SETTINGS_TR_CATEGORY_GENERAL); + } + + QIcon CLogSettingsPage::categoryIcon() const + { + return QIcon(); + } + + QWidget *CLogSettingsPage::createPage(QWidget *parent) + { + m_currentPage = new QWidget(parent); + m_ui.setupUi(m_currentPage); + + readSettings(); + m_ui.errorCheck->setChecked(m_error); + m_ui.warningCheck->setChecked(m_warning); + m_ui.debugCheck->setChecked(m_debug); + m_ui.assertCheck->setChecked(m_assert); + m_ui.infoCheck->setChecked(m_info); + + return m_currentPage; + } + + void CLogSettingsPage::apply() + { + m_error = m_ui.errorCheck->isChecked(); + m_warning = m_ui.warningCheck->isChecked(); + m_debug = m_ui.debugCheck->isChecked(); + m_assert = m_ui.assertCheck->isChecked(); + m_info = m_ui.infoCheck->isChecked(); + + writeSettings(); + m_logPlugin->setDisplayers(); + } + + void CLogSettingsPage::readSettings() + { + QSettings *settings = Core::ICore::instance()->settings(); + + settings->beginGroup(Core::Constants::LOG_SECTION); m_error = settings->value(Core::Constants::LOG_ERROR, true).toBool(); m_warning = settings->value(Core::Constants::LOG_WARNING, true).toBool(); m_debug = settings->value(Core::Constants::LOG_DEBUG, true).toBool(); m_assert = settings->value(Core::Constants::LOG_ASSERT, true).toBool(); - m_info = settings->value(Core::Constants::LOG_INFO, true).toBool(); - settings->endGroup(); - } - - void CLogSettingsPage::writeSettings() - { - QSettings *settings = Core::ICore::instance()->settings(); - - settings->beginGroup(Core::Constants::LOG_SECTION); - settings->setValue(Core::Constants::LOG_ERROR, m_error); - settings->setValue(Core::Constants::LOG_WARNING, m_warning); - settings->setValue(Core::Constants::LOG_DEBUG, m_debug); - settings->setValue(Core::Constants::LOG_ASSERT, m_assert); - settings->setValue(Core::Constants::LOG_INFO, m_info); - settings->endGroup(); - - settings->sync(); - } - + m_info = settings->value(Core::Constants::LOG_INFO, true).toBool(); + settings->endGroup(); + } + + void CLogSettingsPage::writeSettings() + { + QSettings *settings = Core::ICore::instance()->settings(); + + settings->beginGroup(Core::Constants::LOG_SECTION); + settings->setValue(Core::Constants::LOG_ERROR, m_error); + settings->setValue(Core::Constants::LOG_WARNING, m_warning); + settings->setValue(Core::Constants::LOG_DEBUG, m_debug); + settings->setValue(Core::Constants::LOG_ASSERT, m_assert); + settings->setValue(Core::Constants::LOG_INFO, m_info); + settings->endGroup(); + + settings->sync(); + } + } /* namespace Plugin */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.cpp index 35b77b187..e08d8987a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.cpp @@ -26,7 +26,6 @@ #include "nel/3d/u_instance.h" #include "nel/3d/u_light.h" #include "nel/3d/u_3d_mouse_listener.h" -#include "nel/3d/i_program.h" #include "nel/misc/i_xml.h" #include "nel/misc/o_xml.h" #include "nel/misc/file.h" diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.h index 1dffea313..dc19db1c6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.h @@ -1,56 +1,56 @@ -#ifndef MISSION_COMPILER_MAIN_WINDOW_H -#define MISSION_COMPILER_MAIN_WINDOW_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace Ui { - class MissionCompilerMainWindow; -} - -struct CMission; - -class MissionCompilerMainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MissionCompilerMainWindow(QWidget *parent = 0); - ~MissionCompilerMainWindow(); - - void loadConfig(); - void saveConfig(); - QUndoStack *getUndoStack() { return m_undoStack; } - - typedef std::map TMissionContainer; - -public Q_SLOTS: - void handleFilterChanged(const QString &text); - void handleValidation(); - void handleCompile(); - void handlePublish(); - void handleAllDoubleClick(const QModelIndex &index); - void handleSelDoubleClick(const QModelIndex &index); - void handleMoveSelectedRight(); - void handleMoveSelectedLeft(); - void handleMoveAllRight(); - void handleMoveAllLeft(); - void handleDataDirButton(); - void handleDataDirChanged(const QString &text); - void handleResetFiltersButton(); - void handleChangedSettings(); - -private: - Ui::MissionCompilerMainWindow *ui; +#ifndef MISSION_COMPILER_MAIN_WINDOW_H +#define MISSION_COMPILER_MAIN_WINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace Ui { + class MissionCompilerMainWindow; +} + +struct CMission; + +class MissionCompilerMainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MissionCompilerMainWindow(QWidget *parent = 0); + ~MissionCompilerMainWindow(); + + void loadConfig(); + void saveConfig(); + QUndoStack *getUndoStack() { return m_undoStack; } + + typedef std::map TMissionContainer; + +public Q_SLOTS: + void handleFilterChanged(const QString &text); + void handleValidation(); + void handleCompile(); + void handlePublish(); + void handleAllDoubleClick(const QModelIndex &index); + void handleSelDoubleClick(const QModelIndex &index); + void handleMoveSelectedRight(); + void handleMoveSelectedLeft(); + void handleMoveAllRight(); + void handleMoveAllLeft(); + void handleDataDirButton(); + void handleDataDirChanged(const QString &text); + void handleResetFiltersButton(); + void handleChangedSettings(); + +private: + Ui::MissionCompilerMainWindow *ui; void updateCompileLog(); void populateAllPrimitives(const QString &dataDir = QString()); @@ -60,16 +60,16 @@ private: void applyCheckboxes(const QStringList &servers); - QMenu *_toolModeMenu; - QUndoStack *m_undoStack; - QStringListModel *m_allPrimitivesModel; - QStringListModel *m_selectedPrimitivesModel; - QSortFilterProxyModel *m_filteredProxyModel; - QRegExp *m_regexpFilter; - QString m_compileLog; - QString m_lastDir; - - NLLIGO::CLigoConfig m_ligoConfig; -}; - -#endif // MISSION_COMPILER_MAIN_WINDOW_H + QMenu *_toolModeMenu; + QUndoStack *m_undoStack; + QStringListModel *m_allPrimitivesModel; + QStringListModel *m_selectedPrimitivesModel; + QSortFilterProxyModel *m_filteredProxyModel; + QRegExp *m_regexpFilter; + QString m_compileLog; + QString m_lastDir; + + NLLIGO::CLigoConfig m_ligoConfig; +}; + +#endif // MISSION_COMPILER_MAIN_WINDOW_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.ui index dace315ab..3adc8e176 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/mission_compiler_main_window.ui @@ -253,10 +253,7 @@ - horizontalLayoutWidget dataDirLabel - horizontalLayoutWidget - diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.cpp index a9ef08f50..206f0db77 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.cpp @@ -1,63 +1,63 @@ -// Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// Copyright (C) 2011 Dzmitry Kamiahin -// -// 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 . - -// Project includes -#include "server_entry_dialog.h" - -#include "ui_server_entry_dialog.h" - -// NeL includes - -// Qt includes -#include - -namespace MissionCompiler -{ - -ServerEntryDialog::ServerEntryDialog(QWidget *parent) - : QDialog(parent), - m_ui(new Ui::ServerEntryDialog) -{ - m_ui->setupUi(this); - - connect(m_ui->serverTextPathButton, SIGNAL(clicked()), this, SLOT(lookupTextPath())); - connect(m_ui->serverPrimPathButton, SIGNAL(clicked()), this, SLOT(lookupPrimPath())); -} - -ServerEntryDialog::~ServerEntryDialog() -{ - delete m_ui; -} - +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "server_entry_dialog.h" + +#include "ui_server_entry_dialog.h" + +// NeL includes + +// Qt includes +#include + +namespace MissionCompiler +{ + +ServerEntryDialog::ServerEntryDialog(QWidget *parent) + : QDialog(parent), + m_ui(new Ui::ServerEntryDialog) +{ + m_ui->setupUi(this); + + connect(m_ui->serverTextPathButton, SIGNAL(clicked()), this, SLOT(lookupTextPath())); + connect(m_ui->serverPrimPathButton, SIGNAL(clicked()), this, SLOT(lookupPrimPath())); +} + +ServerEntryDialog::~ServerEntryDialog() +{ + delete m_ui; +} + QString ServerEntryDialog::getServerName() { return m_ui->serverNameEdit->text(); } -QString ServerEntryDialog::getTextPath() -{ - return m_ui->serverTextPathEdit->text(); -} - -QString ServerEntryDialog::getPrimPath() -{ - return m_ui->serverPrimPathEdit->text(); -} - +QString ServerEntryDialog::getTextPath() +{ + return m_ui->serverTextPathEdit->text(); +} + +QString ServerEntryDialog::getPrimPath() +{ + return m_ui->serverPrimPathEdit->text(); +} + void ServerEntryDialog::setServerName(QString name) { m_ui->serverNameEdit->setText(name); @@ -68,22 +68,22 @@ void ServerEntryDialog::setTextPath(QString path) m_ui->serverTextPathEdit->setText(path); } -void ServerEntryDialog::setPrimPath(QString path) -{ - m_ui->serverPrimPathEdit->setText(path); -} - -void ServerEntryDialog::lookupTextPath() -{ - QString curPath = m_ui->serverTextPathEdit->text(); - QString path = QFileDialog::getExistingDirectory(this, "", curPath); - m_ui->serverTextPathEdit->setText(path); -} - -void ServerEntryDialog::lookupPrimPath() -{ - QString curPath = m_ui->serverPrimPathEdit->text(); - QString path = QFileDialog::getExistingDirectory(this, "", curPath); - m_ui->serverPrimPathEdit->setText(path); -} +void ServerEntryDialog::setPrimPath(QString path) +{ + m_ui->serverPrimPathEdit->setText(path); +} + +void ServerEntryDialog::lookupTextPath() +{ + QString curPath = m_ui->serverTextPathEdit->text(); + QString path = QFileDialog::getExistingDirectory(this, "", curPath); + m_ui->serverTextPathEdit->setText(path); +} + +void ServerEntryDialog::lookupPrimPath() +{ + QString curPath = m_ui->serverPrimPathEdit->text(); + QString path = QFileDialog::getExistingDirectory(this, "", curPath); + m_ui->serverPrimPathEdit->setText(path); +} } /* namespace MissionCompiler */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.h index 98a086cd0..6dd560876 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/mission_compiler/server_entry_dialog.h @@ -21,8 +21,8 @@ #include -namespace Ui { - class ServerEntryDialog; +namespace Ui { + class ServerEntryDialog; } namespace MissionCompiler diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_system/scheme_manager.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_system/scheme_manager.cpp index 74b5cfbdb..b859d9d66 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_system/scheme_manager.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/particle_system/scheme_manager.cpp @@ -50,8 +50,8 @@ void CSchemeManager::getSchemes(const std::string &type, std::vector -#include -#include -#include -#include - -#include "qnel_widget.h" -#include "painter_dock_widget.h" - -#include "../core/icore.h" -#include "../core/menu_manager.h" -#include "../core/core_constants.h" - -ZonePainterMainWindow::ZonePainterMainWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::ZonePainterMainWindow) -{ - ui->setupUi(this); - m_nelWidget = new NLQT::QNLWidget(this); - setCentralWidget(m_nelWidget); - - // Load the settings. - loadConfig(); - - // Set up dock widget(s) and toolbar. - m_painterDockWidget = new PainterDockWidget(this); - addDockWidget(Qt::RightDockWidgetArea, m_painterDockWidget); - m_painterDockWidget->setVisible(true); - - // Insert tool modes - _toolModeMenu = new QMenu(tr("Tool Mode"), ui->painterToolBar); - _toolModeMenu->setIcon(QIcon(":/painterTools/images/draw-brush.png")); - ui->painterToolBar->addAction(_toolModeMenu->menuAction()); - //connect(_renderModeMenu->menuAction(), SIGNAL(triggered()), this, SLOT(setRenderMode())); - - QSignalMapper *modeMapper = new QSignalMapper(this); - - _toolPaintModeAction = _toolModeMenu->addAction(tr("Paint Mode")); - _toolPaintModeAction->setIcon(QIcon(":/painterTools/images/draw-brush.png")); - _toolPaintModeAction->setStatusTip(tr("Set paint mode")); - connect(_toolPaintModeAction, SIGNAL(triggered()), modeMapper, SLOT(map())); - modeMapper->setMapping(_toolPaintModeAction, 0); - - _toolFillModeAction = _toolModeMenu->addAction(tr("Fill Mode")); - _toolFillModeAction->setStatusTip(tr("Set fill mode")); - _toolFillModeAction->setIcon(QIcon(":/painterTools/images/color-fill.png")); - connect(_toolFillModeAction, SIGNAL(triggered()), modeMapper, SLOT(map())); - modeMapper->setMapping(_toolFillModeAction, 1); - - _toolSelectModeAction = _toolModeMenu->addAction(tr("Select mode")); - _toolSelectModeAction->setIcon(QIcon(":/painterTools/images/go-jump-4.png")); - _toolSelectModeAction->setStatusTip(tr("Set select mode")); - connect(_toolSelectModeAction, SIGNAL(triggered()), modeMapper, SLOT(map())); - modeMapper->setMapping(_toolSelectModeAction, 2); - - _toolPickModeAction = _toolModeMenu->addAction(tr("Pick mode")); - _toolPickModeAction->setIcon(QIcon(":/painterTools/images/color-picker-black.png")); - _toolPickModeAction->setStatusTip(tr("Set color picking mode")); - connect(_toolPickModeAction, SIGNAL(triggered()), modeMapper, SLOT(map())); - modeMapper->setMapping(_toolPickModeAction, 2); - - connect(modeMapper, SIGNAL(mapped(int)), this, SLOT(setToolMode(int))); - - m_statusBarTimer = new QTimer(this); - connect(m_statusBarTimer, SIGNAL(timeout()), this, SLOT(updateStatusBar())); - m_statusInfo = new QLabel(this); - m_statusInfo->hide(); - - // Set Background Color Toolbar - - - connect(ui->actionBackground_Dlg, SIGNAL(triggered()), this, SLOT(setBackgroundColor())); - - - Core::ICore::instance()->mainWindow()->statusBar()->addPermanentWidget(m_statusInfo); - - m_undoStack = new QUndoStack(this); -} - -void ZonePainterMainWindow::showEvent(QShowEvent *showEvent) -{ - QMainWindow::showEvent(showEvent); - m_statusBarTimer->start(1000); - m_statusInfo->show(); -} - -void ZonePainterMainWindow::hideEvent(QHideEvent *hideEvent) -{ - m_statusBarTimer->stop(); - m_statusInfo->hide(); - QMainWindow::hideEvent(hideEvent); -} - -void ZonePainterMainWindow::updateStatusBar() -{ - m_statusInfo->setText(QString("Tool Mode: Paint Mode")); -} - -void ZonePainterMainWindow::setToolMode(int value) -{ - switch (value) - { - case 0: - //Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Point); - break; - case 1: - //Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Line); - break; - case 2: - //Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Filled); - break; - } -} - -void ZonePainterMainWindow::setToolMode() -{ - //switch (Modules::objView().getDriver()->getPolygonMode()) - //{ - //case NL3D::UDriver::Filled: - // Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Line); - // break; - //case NL3D::UDriver::Line: - // Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Point); - // break; - //case NL3D::UDriver::Point: - // Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Filled); - // break; - //} -} - -void ZonePainterMainWindow::setBackgroundColor() { - QColor color = QColorDialog::getColor(QColor(m_nelWidget->backgroundColor().R, - m_nelWidget->backgroundColor().G, - m_nelWidget->backgroundColor().B)); - if (color.isValid()) - m_nelWidget->setBackgroundColor(NLMISC::CRGBA(color.red(), color.green(), color.blue())); -} - -void ZonePainterMainWindow::loadConfig() { +#include "zone_painter_main_window.h" +#include "ui_zone_painter_main_window.h" + +#include +#include +#include +#include +#include + +#include "qnel_widget.h" +#include "painter_dock_widget.h" + +#include "../core/icore.h" +#include "../core/menu_manager.h" +#include "../core/core_constants.h" + +ZonePainterMainWindow::ZonePainterMainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::ZonePainterMainWindow) +{ + ui->setupUi(this); + m_nelWidget = new NLQT::QNLWidget(this); + setCentralWidget(m_nelWidget); + + // Load the settings. + loadConfig(); + + // Set up dock widget(s) and toolbar. + m_painterDockWidget = new PainterDockWidget(this); + addDockWidget(Qt::RightDockWidgetArea, m_painterDockWidget); + m_painterDockWidget->setVisible(true); + + // Insert tool modes + _toolModeMenu = new QMenu(tr("Tool Mode"), ui->painterToolBar); + _toolModeMenu->setIcon(QIcon(":/painterTools/images/draw-brush.png")); + ui->painterToolBar->addAction(_toolModeMenu->menuAction()); + //connect(_renderModeMenu->menuAction(), SIGNAL(triggered()), this, SLOT(setRenderMode())); + + QSignalMapper *modeMapper = new QSignalMapper(this); + + _toolPaintModeAction = _toolModeMenu->addAction(tr("Paint Mode")); + _toolPaintModeAction->setIcon(QIcon(":/painterTools/images/draw-brush.png")); + _toolPaintModeAction->setStatusTip(tr("Set paint mode")); + connect(_toolPaintModeAction, SIGNAL(triggered()), modeMapper, SLOT(map())); + modeMapper->setMapping(_toolPaintModeAction, 0); + + _toolFillModeAction = _toolModeMenu->addAction(tr("Fill Mode")); + _toolFillModeAction->setStatusTip(tr("Set fill mode")); + _toolFillModeAction->setIcon(QIcon(":/painterTools/images/color-fill.png")); + connect(_toolFillModeAction, SIGNAL(triggered()), modeMapper, SLOT(map())); + modeMapper->setMapping(_toolFillModeAction, 1); + + _toolSelectModeAction = _toolModeMenu->addAction(tr("Select mode")); + _toolSelectModeAction->setIcon(QIcon(":/painterTools/images/go-jump-4.png")); + _toolSelectModeAction->setStatusTip(tr("Set select mode")); + connect(_toolSelectModeAction, SIGNAL(triggered()), modeMapper, SLOT(map())); + modeMapper->setMapping(_toolSelectModeAction, 2); + + _toolPickModeAction = _toolModeMenu->addAction(tr("Pick mode")); + _toolPickModeAction->setIcon(QIcon(":/painterTools/images/color-picker-black.png")); + _toolPickModeAction->setStatusTip(tr("Set color picking mode")); + connect(_toolPickModeAction, SIGNAL(triggered()), modeMapper, SLOT(map())); + modeMapper->setMapping(_toolPickModeAction, 2); + + connect(modeMapper, SIGNAL(mapped(int)), this, SLOT(setToolMode(int))); + + m_statusBarTimer = new QTimer(this); + connect(m_statusBarTimer, SIGNAL(timeout()), this, SLOT(updateStatusBar())); + m_statusInfo = new QLabel(this); + m_statusInfo->hide(); + + // Set Background Color Toolbar + + + connect(ui->actionBackground_Dlg, SIGNAL(triggered()), this, SLOT(setBackgroundColor())); + + + Core::ICore::instance()->mainWindow()->statusBar()->addPermanentWidget(m_statusInfo); + + m_undoStack = new QUndoStack(this); +} + +void ZonePainterMainWindow::showEvent(QShowEvent *showEvent) +{ + QMainWindow::showEvent(showEvent); + m_statusBarTimer->start(1000); + m_statusInfo->show(); +} + +void ZonePainterMainWindow::hideEvent(QHideEvent *hideEvent) +{ + m_statusBarTimer->stop(); + m_statusInfo->hide(); + QMainWindow::hideEvent(hideEvent); +} + +void ZonePainterMainWindow::updateStatusBar() +{ + m_statusInfo->setText(QString("Tool Mode: Paint Mode")); +} + +void ZonePainterMainWindow::setToolMode(int value) +{ + switch (value) + { + case 0: + //Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Point); + break; + case 1: + //Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Line); + break; + case 2: + //Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Filled); + break; + } +} + +void ZonePainterMainWindow::setToolMode() +{ + //switch (Modules::objView().getDriver()->getPolygonMode()) + //{ + //case NL3D::UDriver::Filled: + // Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Line); + // break; + //case NL3D::UDriver::Line: + // Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Point); + // break; + //case NL3D::UDriver::Point: + // Modules::objView().getDriver()->setPolygonMode (NL3D::UDriver::Filled); + // break; + //} +} + +void ZonePainterMainWindow::setBackgroundColor() { + QColor color = QColorDialog::getColor(QColor(m_nelWidget->backgroundColor().R, + m_nelWidget->backgroundColor().G, + m_nelWidget->backgroundColor().B)); + if (color.isValid()) + m_nelWidget->setBackgroundColor(NLMISC::CRGBA(color.red(), color.green(), color.blue())); +} + +void ZonePainterMainWindow::loadConfig() { QSettings *settings = Core::ICore::instance()->settings(); settings->beginGroup("ZonePainter"); QColor color; color = settings->value("BackgroundColor", QColor(80, 80, 80)).value(); settings->endGroup(); - m_nelWidget->setBackgroundColor(NLMISC::CRGBA(color.red(), color.green(), color.blue(), color.alpha())); -} - -void ZonePainterMainWindow::saveConfig() { + m_nelWidget->setBackgroundColor(NLMISC::CRGBA(color.red(), color.green(), color.blue(), color.alpha())); +} + +void ZonePainterMainWindow::saveConfig() { QSettings *settings = Core::ICore::instance()->settings(); settings->beginGroup("ZonePainter" ); @@ -157,12 +157,12 @@ void ZonePainterMainWindow::saveConfig() { settings->setValue("BackgroundColor", color); settings->endGroup(); - settings->sync(); -} - -ZonePainterMainWindow::~ZonePainterMainWindow() -{ - delete ui; - delete m_nelWidget; - delete m_painterDockWidget; -} + settings->sync(); +} + +ZonePainterMainWindow::~ZonePainterMainWindow() +{ + delete ui; + delete m_nelWidget; + delete m_painterDockWidget; +} diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.h index 0dbfd9948..caa4433e4 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/zone_painter/zone_painter_main_window.h @@ -1,57 +1,57 @@ -#ifndef ZONE_PAINTER_MAIN_WINDOW_H -#define ZONE_PAINTER_MAIN_WINDOW_H - -#include -#include -#include -#include -#include - -namespace NLQT { - class QNLWidget; -} - -namespace Ui { - class ZonePainterMainWindow; -} - -class PainterDockWidget; - -class ZonePainterMainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit ZonePainterMainWindow(QWidget *parent = 0); - ~ZonePainterMainWindow(); - - void loadConfig(); - void saveConfig(); - QUndoStack *getUndoStack() { return m_undoStack; } -public Q_SLOTS: +#ifndef ZONE_PAINTER_MAIN_WINDOW_H +#define ZONE_PAINTER_MAIN_WINDOW_H + +#include +#include +#include +#include +#include + +namespace NLQT { + class QNLWidget; +} + +namespace Ui { + class ZonePainterMainWindow; +} + +class PainterDockWidget; + +class ZonePainterMainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit ZonePainterMainWindow(QWidget *parent = 0); + ~ZonePainterMainWindow(); + + void loadConfig(); + void saveConfig(); + QUndoStack *getUndoStack() { return m_undoStack; } +public Q_SLOTS: void setToolMode(int value); - void setToolMode(); - void updateStatusBar(); - void setBackgroundColor(); - -protected: - virtual void showEvent(QShowEvent *showEvent); - virtual void hideEvent(QHideEvent *hideEvent); - -private: - Ui::ZonePainterMainWindow *ui; - NLQT::QNLWidget *m_nelWidget; - PainterDockWidget *m_painterDockWidget; - QTimer *m_statusBarTimer; - QLabel *m_statusInfo; - + void setToolMode(); + void updateStatusBar(); + void setBackgroundColor(); + +protected: + virtual void showEvent(QShowEvent *showEvent); + virtual void hideEvent(QHideEvent *hideEvent); + +private: + Ui::ZonePainterMainWindow *ui; + NLQT::QNLWidget *m_nelWidget; + PainterDockWidget *m_painterDockWidget; + QTimer *m_statusBarTimer; + QLabel *m_statusInfo; + QAction *_toolPaintModeAction; QAction *_toolFillModeAction; QAction *_toolSelectModeAction; QAction *_toolPickModeAction; - QMenu *_toolModeMenu; - QUndoStack *m_undoStack; - //QAction *m_setBackColorAction; -}; - -#endif // ZONE_PAINTER_MAIN_WINDOW_H + QMenu *_toolModeMenu; + QUndoStack *m_undoStack; + //QAction *m_setBackColorAction; +}; + +#endif // ZONE_PAINTER_MAIN_WINDOW_H diff --git a/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.cpp b/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.cpp index 70bf51f81..af026b3df 100644 --- a/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.cpp +++ b/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.cpp @@ -1,724 +1,724 @@ -/* -Object Viewer Qt Widget -Copyright (C) 2010 Adrian Jaekel - -This program 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 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 General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "object_viewer_widget.h" - -// STL includes - -// NeL includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Qt includes -#include - -// Project includes - -Q_EXPORT_PLUGIN2(object_viewer_widget_qt, NLQT::CObjectViewerWidget) - -using namespace NLMISC; -using namespace NL3D; -using namespace std; - -namespace NLQT -{ - CObjectViewerWidget *CObjectViewerWidget::_objectViewerWidget = NULL; - - CObjectViewerWidget::CObjectViewerWidget(QWidget *parent) - : _isGraphicsInitialized(false), _isGraphicsEnabled(false), - _Driver(NULL), _Light(0), _phi(0), _psi(0),_dist(2), - _CameraFocal(75), _CurrentInstance(""), _BloomEffect(false), - _Scene(0), QWidget(parent) - { +/* +Object Viewer Qt Widget +Copyright (C) 2010 Adrian Jaekel + +This program 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 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "object_viewer_widget.h" + +// STL includes + +// NeL includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Qt includes +#include + +// Project includes + +Q_EXPORT_PLUGIN2(object_viewer_widget_qt, NLQT::CObjectViewerWidget) + +using namespace NLMISC; +using namespace NL3D; +using namespace std; + +namespace NLQT +{ + CObjectViewerWidget *CObjectViewerWidget::_objectViewerWidget = NULL; + + CObjectViewerWidget::CObjectViewerWidget(QWidget *parent) + : _isGraphicsInitialized(false), _isGraphicsEnabled(false), + _Driver(NULL), _Light(0), _phi(0), _psi(0),_dist(2), + _CameraFocal(75), _CurrentInstance(""), _BloomEffect(false), + _Scene(0), QWidget(parent) + { + setMouseTracking(true); + setFocusPolicy(Qt::StrongFocus); + _objectViewerWidget = this; + + _isGraphicsEnabled = true; + + // As a special case, a QTimer with a timeout of 0 will time out as soon as all the events in the window system's event queue have been processed. + // This can be used to do heavy work while providing a snappy user interface. + _mainTimer = new QTimer(this); + connect(_mainTimer, SIGNAL(timeout()), this, SLOT(updateRender())); + // timer->start(); // <- timeout 0 + // it's heavy on cpu, though, when no 3d driver initialized :) + _mainTimer->start(25); // 25fps + } + + CObjectViewerWidget::~CObjectViewerWidget() + { + release(); + } + + void CObjectViewerWidget::showEvent ( QShowEvent * event ) + { + if (!_mainTimer->isActive()) + { + _mainTimer->start(25); + } + } + + void CObjectViewerWidget::setNelContext(NLMISC::INelContext &nelContext) + { + _LibContext = new CLibraryContext(nelContext); + } + + void CObjectViewerWidget::init() + { + + connect(this, SIGNAL(topLevelChanged(bool)), + this, SLOT(topLevelChanged(bool))); + //H_AUTO2 + //nldebug("%d %d %d",_nlw->winId(), width(), height()); + + +#if defined(NL_OS_UNIX) && !defined(NL_OS_MAC) + //dynamic_cast(widget())->makeCurrent(); +#endif // defined(NL_OS_UNIX) && !defined(NL_OS_MAC) + + nlWindow wnd = (nlWindow)winId(); + uint16 w = width(); + uint16 h = height(); + setMouseTracking(true); - setFocusPolicy(Qt::StrongFocus); - _objectViewerWidget = this; - - _isGraphicsEnabled = true; - - // As a special case, a QTimer with a timeout of 0 will time out as soon as all the events in the window system's event queue have been processed. - // This can be used to do heavy work while providing a snappy user interface. - _mainTimer = new QTimer(this); - connect(_mainTimer, SIGNAL(timeout()), this, SLOT(updateRender())); - // timer->start(); // <- timeout 0 - // it's heavy on cpu, though, when no 3d driver initialized :) - _mainTimer->start(25); // 25fps - } - - CObjectViewerWidget::~CObjectViewerWidget() - { - release(); - } - - void CObjectViewerWidget::showEvent ( QShowEvent * event ) - { - if (!_mainTimer->isActive()) - { - _mainTimer->start(25); - } - } - - void CObjectViewerWidget::setNelContext(NLMISC::INelContext &nelContext) - { - _LibContext = new CLibraryContext(nelContext); - } - - void CObjectViewerWidget::init() - { - - connect(this, SIGNAL(topLevelChanged(bool)), - this, SLOT(topLevelChanged(bool))); - //H_AUTO2 - //nldebug("%d %d %d",_nlw->winId(), width(), height()); - - -#if defined(NL_OS_UNIX) && !defined(NL_OS_MAC) - //dynamic_cast(widget())->makeCurrent(); -#endif // defined(NL_OS_UNIX) && !defined(NL_OS_MAC) - - nlWindow wnd = (nlWindow)winId(); - uint16 w = width(); - uint16 h = height(); - - setMouseTracking(true); - - // set background color from config - //NLMISC::CConfigFile::CVar v = Modules::config().getConfigFile().getVar("BackgroundColor"); - //_BackgroundColor = CRGBA(v.asInt(0), v.asInt(1), v.asInt(2)); - _BackgroundColor = CRGBA(255, 255, 255); - - // set graphics driver from config - //NLMISC::CConfigFile::CVar v2 = Modules::config().getConfigFile().getVar("GraphicsDriver"); - // Choose driver opengl to work correctly under Linux example - _Direct3D = false; //_Driver = OpenGL; - -#ifdef NL_OS_WINDOWS - //std::string driver = v2.asString(); - //if (driver == "Direct3D") _Direct3D = true; //m_Driver = Direct3D; - //else if (driver == "OpenGL") _Direct3D = false; //m_Driver = OpenGL; - //else nlwarning("Invalid driver specified, defaulting to OpenGL"); -#endif - - //Modules::config().setAndCallback("CameraFocal",CConfigCallback(this,&CObjectViewer::cfcbCameraFocal)); - //Modules::config().setAndCallback("BloomEffect",CConfigCallback(this,&CObjectViewer::cfcbBloomEffect)); - - // create the driver - nlassert(!_Driver); - - _Driver = UDriver::createDriver(0, _Direct3D, 0); - nlassert(_Driver); - - // initialize the window with config file values - _Driver->setDisplay(wnd, NL3D::UDriver::CMode(w, h, 32)); - - //_Light = ULight::createLight(); - - //// set mode of the light - //_Light->setMode(ULight::DirectionalLight); - - //// set position of the light - //_Light->setPosition(CVector(-20.f, 30.f, 10.f)); - - //// white light - //_Light->setAmbiant(CRGBA(255, 255, 255)); - - //// set and enable the light - //_Driver->setLight(0, *_Light); - //_Driver->enableLight(0); - - // Create a scene - _Scene = _Driver->createScene(true); - - _PlayListManager = _Scene->createPlayListManager(); - - //_Scene->enableLightingSystem(true); - - // create the camera - UCamera camera = _Scene->getCam(); - - camera.setTransformMode (UTransformable::DirectMatrix); - - setSizeViewport(w, h); - - // camera will look at entities - camera.lookAt(NLMISC::CVector(_dist,0,1), NLMISC::CVector(0,0,0.5)); - - NLMISC::CVector hotSpot=NLMISC::CVector(0,0,0); - - _MouseListener = _Driver->create3dMouseListener(); - _MouseListener->setMatrix(_Scene->getCam().getMatrix()); - _MouseListener->setFrustrum(_Scene->getCam().getFrustum()); - _MouseListener->setHotSpot(hotSpot); - _MouseListener->setMouseMode(U3dMouseListener::edit3d); - - NL3D::CBloomEffect::instance().setDriver(_Driver); - NL3D::CBloomEffect::instance().setScene(_Scene); - NL3D::CBloomEffect::instance().init(!_Direct3D); - //NL3D::CBloomEffect::instance().setDensityBloom(Modules::config().getConfigFile().getVar("BloomDensity").asInt()); - //NL3D::CBloomEffect::instance().setSquareBloom(Modules::config().getConfigFile().getVar("BloomSquare").asBool()); - } - - void CObjectViewerWidget::release() - { - //H_AUTO2 - nldebug(""); - - _Driver->delete3dMouseListener(_MouseListener); - - // delete all entities - deleteEntities(); - - _Scene->deletePlayListManager(_PlayListManager); - - // delete the scene - _Driver->deleteScene(_Scene); - - // delete the light - delete _Light; - - // release driver - nlassert(_Driver); - _Driver->release(); - delete _Driver; - _Driver = NULL; - } - - void CObjectViewerWidget::updateRender() - { - //nldebug("CMainWindow::updateRender"); - updateInitialization(isVisible()); - - //QModelIndex index = _dirModel->setRootPath("D:/Dev/Ryzom/code/ryzom/common/data_leveldesign/leveldesign"); - //_dirTree->setRootIndex(index); - - if (isVisible()) - { - // call all update functions - // 01. Update Utilities (configuration etc) - - // 02. Update Time (deltas) - // ... - - // 03. Update Receive (network, servertime, receive messages) - // ... - - // 04. Update Input (keyboard controls, etc) - if (_isGraphicsInitialized) - updateInput(); - - // 05. Update Weather (sky, snow, wind, fog, sun) - // ... - - // 06. Update Entities (movement, do after possible tp from incoming messages etc) - // - Move other entities - // - Update self entity - // - Move bullets - // ... - - // 07. Update Landscape (async zone loading near entity) - // ... - - // 08. Update Collisions (entities) - // - Update entities - // - Update move container (swap with Update entities? todo: check code!) - // - Update bullets - // ... - - // 09. Update Animations (playlists) - // - Needs to be either before or after entities, not sure, - // there was a problem with wrong order a while ago!!! - - - //updateAnimation(_AnimationDialog->getTime()); - updateAnimatePS(); - // 10. Update Camera (depends on entities) - // ... - - // 11. Update Interface (login, ui, etc) - // ... - - // 12. Update Sound (sound driver) - // ... - - // 13. Update Send (network, send new position etc) - // ... - - // 14. Update Debug (stuff for dev) - // ... - - if (_isGraphicsInitialized && !getDriver()->isLost()) - { - // 01. Render Driver (background color) - renderDriver(); // clear all buffers - - // 02. Render Sky (sky scene) - // ... - - // 04. Render Scene (entity scene) - renderScene(); - - // 05. Render Effects (flare) - // ... - - // 06. Render Interface 3D (player names) - // ... - - // 07. Render Debug 3D - // ... - - // 08. Render Interface 2D (chatboxes etc, optionally does have 3d) - // ... - - // 09. Render Debug 2D (stuff for dev) - renderDebug2D(); - - // swap 3d buffers - getDriver()->swapBuffers(); - } - } - } - - void CObjectViewerWidget::updateInitialization(bool visible) - { - //nldebug("CMainWindow::updateInitialization"); - bool done; - do - { - done = true; // set false whenever change - bool wantGraphics = _isGraphicsEnabled && visible; - // bool wantLandscape = wantGraphics && m_IsGraphicsInitialized && isLandscapeEnabled; - - // .. stuff that depends on other stuff goes on top to prioritize deinitialization - - // Landscape - // ... - - // Graphics (Driver) - if (_isGraphicsInitialized) - { - if (!wantGraphics) - { - //_isGraphicsInitialized = false; - //release(); - _mainTimer->stop(); - //done = false; - } - } - else - { - if (wantGraphics) - { - init(); - _isGraphicsInitialized = true; - _mainTimer->start(25); - //done = false; - } - } - } - while (!done); - } - - void CObjectViewerWidget::updateInput() - { - _Driver->EventServer.pump(); - - // New matrix from camera - _Scene->getCam().setTransformMode(NL3D::UTransformable::DirectMatrix); - _Scene->getCam().setMatrix (_MouseListener->getViewMatrix()); - - //nldebug("%s",_Scene->getCam().getMatrix().getPos().asString().c_str()); - } - - void CObjectViewerWidget::renderDriver() - { - // Render the scene. - if((NL3D::CBloomEffect::instance().getDriver() != NULL) && (_BloomEffect)) - { - NL3D::CBloomEffect::instance().initBloom(); - } - _Driver->clearBuffers(_BackgroundColor); - } - - void CObjectViewerWidget::renderScene() - { - // render the scene - _Scene->render(); - - if((NL3D::CBloomEffect::instance().getDriver() != NULL) && (_BloomEffect)) - { - NL3D::CBloomEffect::instance().endBloom(); - NL3D::CBloomEffect::instance().endInterfacesDisplayBloom(); - } - } - - void CObjectViewerWidget::renderDebug2D() - { - } - - void CObjectViewerWidget::saveScreenshot(const std::string &nameFile, bool jpg, bool png, bool tga) - { - //H_AUTO2 - - // FIXME: create screenshot path if it doesn't exist! - - // empty bitmap - CBitmap bitmap; - // copy the driver buffer to the bitmap - _Driver->getBuffer(bitmap); - // create the file name - string filename = std::string("./") + nameFile; - // write the bitmap as a jpg, png or tga to the file - if (jpg) - { - string newfilename = CFile::findNewFile(filename + ".jpg"); - COFile outputFile(newfilename); - bitmap.writeJPG(outputFile, 100); - nlinfo("Screenshot '%s' saved", newfilename.c_str()); - } - if (png) - { - string newfilename = CFile::findNewFile(filename + ".png"); - COFile outputFile(newfilename); - bitmap.writePNG(outputFile, 24); - nlinfo("Screenshot '%s' saved", newfilename.c_str()); - } - if (tga) - { - string newfilename = CFile::findNewFile(filename + ".tga"); - COFile outputFile(newfilename); - bitmap.writeTGA(outputFile, 24, false); - nlinfo("Screenshot '%s' saved", newfilename.c_str()); - } - } - - bool CObjectViewerWidget::loadMesh(const std::string &meshFileName, const std::string &skelFileName) - { - std::string fileName = CFile::getFilenameWithoutExtension(meshFileName); - if ( _Entities.count(fileName) != 0) - return false; - - CPath::addSearchPath(CFile::getPath(meshFileName), false, false); - - // create instance of the mesh character - UInstance Entity = _Scene->createInstance(meshFileName); - - CAABBox bbox; - Entity.getShapeAABBox(bbox); - setCamera(_Scene, bbox , Entity, true); - - _MouseListener->setMatrix(_Scene->getCam().getMatrix()); - - USkeleton Skeleton = _Scene->createSkeleton(skelFileName); - - // if we can't create entity, skip it - if (Entity.empty()) return false; - - // create a new entity - EIT eit = (_Entities.insert (make_pair (fileName, CEntity()))).first; - CEntity &entity = (*eit).second; - - // set the entity up - entity._Name = fileName; - entity._FileNameShape = meshFileName; - entity._FileNameSkeleton = skelFileName; - entity._Instance = Entity; - if (!Skeleton.empty()) - { - entity._Skeleton = Skeleton; - entity._Skeleton.bindSkin (entity._Instance); - } - entity._AnimationSet = _Driver->createAnimationSet(false); - entity._PlayList = _PlayListManager->createPlayList(entity._AnimationSet); - return true; - } - - void CObjectViewerWidget::setVisible(bool visible) - { - // called by show() - // code assuming visible window needed to init the 3d driver - nldebug("%d", visible); - if (visible) - { - QWidget::setVisible(true); - } - else - { - QWidget::setVisible(false); - } - } - - void CObjectViewerWidget::resetScene() - { - deleteEntities(); - - // Reset camera. - //.. - - // to load files with the same name but located in different directories - //CPath::clearMap(); - - // load and set search paths from config - //Modules::config().configSearchPaths(); - - _CurrentInstance = ""; - - nlinfo("Scene cleared"); - } - - void CObjectViewerWidget::setBackgroundColor(NLMISC::CRGBA backgroundColor) - { - _BackgroundColor = backgroundColor; - - // config file variable changes - //Modules::config().getConfigFile().getVar("BackgroundColor").setAsInt(_BackgroundColor.R, 0); - //Modules::config().getConfigFile().getVar("BackgroundColor").setAsInt(_BackgroundColor.G, 1); - //Modules::config().getConfigFile().getVar("BackgroundColor").setAsInt(_BackgroundColor.B, 2); - } - - void CObjectViewerWidget::setGraphicsDriver(bool Direct3D) - { - //_Direct3D = Direct3D; - - //if (_Direct3D) Modules::config().getConfigFile().getVar("GraphicsDriver").setAsString("Direct3D"); - //else Modules::config().getConfigFile().getVar("GraphicsDriver").setAsString("OpenGL"); - } - - void CObjectViewerWidget::setSizeViewport(uint16 w, uint16 h) - { - _Scene->getCam().setPerspective(_CameraFocal * (float)Pi/180.f, (float)w/h, 0.1f, 1000); - } - - void CObjectViewerWidget::setCurrentObject(const std::string &name) - { - if ((_Entities.count(name) != 0) || ( name.empty() )) _CurrentInstance = name; - else nlerror ("Entity %s not found", name.c_str()); - nlinfo("set current entity %s", _CurrentInstance.c_str()); - } - - CEntity& CObjectViewerWidget::getEntity(const std::string &name) - { - if ( _Entities.count(name) == 0) nlerror("Entity %s not found", name.c_str()); - EIT eit = _Entities.find (name); - return (*eit).second; - } - - void CObjectViewerWidget::getListObjects(std::vector &listObj) - { - listObj.clear(); - for (EIT eit = _Entities.begin(); eit != _Entities.end(); ++eit) - listObj.push_back((*eit).second._Name); - } - - void CObjectViewerWidget::deleteEntity(CEntity &entity) - { - if (entity._PlayList != NULL) - { - _PlayListManager->deletePlayList (entity._PlayList); - entity._PlayList = NULL; - } - - if (entity._AnimationSet != NULL) - { - _Driver->deleteAnimationSet(entity._AnimationSet); - entity._AnimationSet = NULL; - } - - if (!entity._Skeleton.empty()) - { - entity._Skeleton.detachSkeletonSon(entity._Instance); - - _Scene->deleteSkeleton(entity._Skeleton); - entity._Skeleton = NULL; - } - - if (!entity._Instance.empty()) - { - _Scene->deleteInstance(entity._Instance); - entity._Instance = NULL; - } - } - - void CObjectViewerWidget::deleteEntities() - { - for (EIT eit = _Entities.begin(); eit != _Entities.end(); ++eit) - { - CEntity &entity = (*eit).second; - deleteEntity(entity); - } - _Entities.clear(); - } - - void CObjectViewerWidget::setCamera(NL3D::UScene *scene, CAABBox &bbox, UTransform &entity, bool high_z) - { - CVector pos(0.f, 0.f, 0.f); - CQuat quat(0.f, 0.f, 0.f, 0.f); - NL3D::UInstance inst; - inst.cast(entity); - if (!inst.empty()) - { - inst.getDefaultPos(pos); - inst.getDefaultRotQuat(quat); - } - - // fix scale (some shapes have a different value) - entity.setScale(1.f, 1.f, 1.f); - - UCamera Camera = scene->getCam(); - CVector max_radius = bbox.getHalfSize(); - - CVector center = bbox.getCenter(); - entity.setPivot(center); - center += pos; - - //scene->getCam().setPerspective(_CameraFocal * (float)Pi/180.f, (float)w/h, 0.1f, 1000); - float fov = float(_CameraFocal * (float)Pi/180.0); - //Camera.setPerspective (fov, 1.0f, 0.1f, 1000.0f); - float radius = max(max(max_radius.x, max_radius.y), max_radius.z); - if (radius == 0.f) radius = 1.f; - float left, right, bottom, top, znear, zfar; - Camera.getFrustum(left, right, bottom, top, znear, zfar); - float dist = (radius / (tan(fov/2))) * 0.2; - CVector eye(center); - CVector ax(quat.getAxis()); - - if (ax.isNull() || ax == CVector::I) - { - ax = CVector::J; - } - else if (ax == -CVector::K) - { - ax = -CVector::J; - } - - eye -= ax * (dist+radius); - if (high_z) - eye.z += max_radius.z/1.0f; - Camera.lookAt(eye, center); - setupLight(eye, center - eye); - } - - bool CObjectViewerWidget::setupLight(const CVector &position, const CVector &direction) - { - if (!_Light) - _Light = ULight::createLight(); - if (!_Light) return false; - - // set mode of the light - _Light->setMode(ULight::DirectionalLight); - - // set position of the light - // Light->setupDirectional(settings.light_ambiant, settings.light_diffuse, settings.light_specular, settings.light_direction); - NLMISC::CRGBA light_ambiant = CRGBA(0,0,0); - NLMISC::CRGBA light_diffuse = CRGBA(255,255,255); - NLMISC::CRGBA light_specular = CRGBA(255,255,255); - NLMISC::CVector light_direction = CVector(0.25, 0.25, 0.25); - _Light->setupPointLight(light_ambiant, light_diffuse, light_specular, position, direction + light_direction); - - // set and enable the light - _Driver->setLight(0, *_Light); - _Driver->enableLight(0); - - return true; - } - - QIcon* CObjectViewerWidget::saveOneImage(string shapename) - { - int output_width = 128; - int output_height = 128; - - // Create a scene - NL3D::UScene* Scene = _Driver->createScene(true); - if (!Scene) return 0; - - // get scene camera - if (Scene->getCam().empty()) - { - nlwarning("can't get camera from scene"); - return 0; - } - - // add an entity to the scene - UInstance Entity = Scene->createInstance(shapename.c_str()); - - // if we can't create entity, skip it - if (Entity.empty()) - { - nlwarning("can't create instance from %s", shapename.c_str()); - return 0; - } - - // get AABox of Entity - CAABBox bbox; - Entity.getShapeAABBox(bbox); - setCamera(Scene, bbox , Entity, true); - Scene->getCam().setPerspective(_CameraFocal * (float)Pi/180.f, (float)output_width/output_height, 0.1f, 1000); - - string filename = CPath::standardizePath("") + toString("%s.%s", shapename.c_str(), "png"); - - // the background is white - _Driver->clearBuffers(); - - // render the scene - Scene->render(); - - CBitmap btm; - _Driver->getBuffer(btm); - - btm.resample(output_width, output_height); - - COFile fs; - - if (fs.open(filename)) - { - if (!btm.writePNG(fs, 24)) - { - nlwarning("can't save image to PNG"); - return 0; - } - } - else - { - nlwarning("can't create %s", "test.png"); - return 0; - } - fs.close(); - - QIcon *icon = new QIcon(QString(filename.c_str())); - //CFile::deleteFile(filename); - return icon; - } + + // set background color from config + //NLMISC::CConfigFile::CVar v = Modules::config().getConfigFile().getVar("BackgroundColor"); + //_BackgroundColor = CRGBA(v.asInt(0), v.asInt(1), v.asInt(2)); + _BackgroundColor = CRGBA(255, 255, 255); + + // set graphics driver from config + //NLMISC::CConfigFile::CVar v2 = Modules::config().getConfigFile().getVar("GraphicsDriver"); + // Choose driver opengl to work correctly under Linux example + _Direct3D = false; //_Driver = OpenGL; + +#ifdef NL_OS_WINDOWS + //std::string driver = v2.asString(); + //if (driver == "Direct3D") _Direct3D = true; //m_Driver = Direct3D; + //else if (driver == "OpenGL") _Direct3D = false; //m_Driver = OpenGL; + //else nlwarning("Invalid driver specified, defaulting to OpenGL"); +#endif + + //Modules::config().setAndCallback("CameraFocal",CConfigCallback(this,&CObjectViewer::cfcbCameraFocal)); + //Modules::config().setAndCallback("BloomEffect",CConfigCallback(this,&CObjectViewer::cfcbBloomEffect)); + + // create the driver + nlassert(!_Driver); + + _Driver = UDriver::createDriver(0, _Direct3D, 0); + nlassert(_Driver); + + // initialize the window with config file values + _Driver->setDisplay(wnd, NL3D::UDriver::CMode(w, h, 32)); + + //_Light = ULight::createLight(); + + //// set mode of the light + //_Light->setMode(ULight::DirectionalLight); + + //// set position of the light + //_Light->setPosition(CVector(-20.f, 30.f, 10.f)); + + //// white light + //_Light->setAmbiant(CRGBA(255, 255, 255)); + + //// set and enable the light + //_Driver->setLight(0, *_Light); + //_Driver->enableLight(0); + + // Create a scene + _Scene = _Driver->createScene(true); + + _PlayListManager = _Scene->createPlayListManager(); + + //_Scene->enableLightingSystem(true); + + // create the camera + UCamera camera = _Scene->getCam(); + + camera.setTransformMode (UTransformable::DirectMatrix); + + setSizeViewport(w, h); + + // camera will look at entities + camera.lookAt(NLMISC::CVector(_dist,0,1), NLMISC::CVector(0,0,0.5)); + + NLMISC::CVector hotSpot=NLMISC::CVector(0,0,0); + + _MouseListener = _Driver->create3dMouseListener(); + _MouseListener->setMatrix(_Scene->getCam().getMatrix()); + _MouseListener->setFrustrum(_Scene->getCam().getFrustum()); + _MouseListener->setHotSpot(hotSpot); + _MouseListener->setMouseMode(U3dMouseListener::edit3d); + + NL3D::CBloomEffect::instance().setDriver(_Driver); + NL3D::CBloomEffect::instance().setScene(_Scene); + NL3D::CBloomEffect::instance().init(!_Direct3D); + //NL3D::CBloomEffect::instance().setDensityBloom(Modules::config().getConfigFile().getVar("BloomDensity").asInt()); + //NL3D::CBloomEffect::instance().setSquareBloom(Modules::config().getConfigFile().getVar("BloomSquare").asBool()); + } + + void CObjectViewerWidget::release() + { + //H_AUTO2 + nldebug(""); + + _Driver->delete3dMouseListener(_MouseListener); + + // delete all entities + deleteEntities(); + + _Scene->deletePlayListManager(_PlayListManager); + + // delete the scene + _Driver->deleteScene(_Scene); + + // delete the light + delete _Light; + + // release driver + nlassert(_Driver); + _Driver->release(); + delete _Driver; + _Driver = NULL; + } + + void CObjectViewerWidget::updateRender() + { + //nldebug("CMainWindow::updateRender"); + updateInitialization(isVisible()); + + //QModelIndex index = _dirModel->setRootPath("D:/Dev/Ryzom/code/ryzom/common/data_leveldesign/leveldesign"); + //_dirTree->setRootIndex(index); + + if (isVisible()) + { + // call all update functions + // 01. Update Utilities (configuration etc) + + // 02. Update Time (deltas) + // ... + + // 03. Update Receive (network, servertime, receive messages) + // ... + + // 04. Update Input (keyboard controls, etc) + if (_isGraphicsInitialized) + updateInput(); + + // 05. Update Weather (sky, snow, wind, fog, sun) + // ... + + // 06. Update Entities (movement, do after possible tp from incoming messages etc) + // - Move other entities + // - Update self entity + // - Move bullets + // ... + + // 07. Update Landscape (async zone loading near entity) + // ... + + // 08. Update Collisions (entities) + // - Update entities + // - Update move container (swap with Update entities? todo: check code!) + // - Update bullets + // ... + + // 09. Update Animations (playlists) + // - Needs to be either before or after entities, not sure, + // there was a problem with wrong order a while ago!!! + + + //updateAnimation(_AnimationDialog->getTime()); + updateAnimatePS(); + // 10. Update Camera (depends on entities) + // ... + + // 11. Update Interface (login, ui, etc) + // ... + + // 12. Update Sound (sound driver) + // ... + + // 13. Update Send (network, send new position etc) + // ... + + // 14. Update Debug (stuff for dev) + // ... + + if (_isGraphicsInitialized && !getDriver()->isLost()) + { + // 01. Render Driver (background color) + renderDriver(); // clear all buffers + + // 02. Render Sky (sky scene) + // ... + + // 04. Render Scene (entity scene) + renderScene(); + + // 05. Render Effects (flare) + // ... + + // 06. Render Interface 3D (player names) + // ... + + // 07. Render Debug 3D + // ... + + // 08. Render Interface 2D (chatboxes etc, optionally does have 3d) + // ... + + // 09. Render Debug 2D (stuff for dev) + renderDebug2D(); + + // swap 3d buffers + getDriver()->swapBuffers(); + } + } + } + + void CObjectViewerWidget::updateInitialization(bool visible) + { + //nldebug("CMainWindow::updateInitialization"); + bool done; + do + { + done = true; // set false whenever change + bool wantGraphics = _isGraphicsEnabled && visible; + // bool wantLandscape = wantGraphics && m_IsGraphicsInitialized && isLandscapeEnabled; + + // .. stuff that depends on other stuff goes on top to prioritize deinitialization + + // Landscape + // ... + + // Graphics (Driver) + if (_isGraphicsInitialized) + { + if (!wantGraphics) + { + //_isGraphicsInitialized = false; + //release(); + _mainTimer->stop(); + //done = false; + } + } + else + { + if (wantGraphics) + { + init(); + _isGraphicsInitialized = true; + _mainTimer->start(25); + //done = false; + } + } + } + while (!done); + } + + void CObjectViewerWidget::updateInput() + { + _Driver->EventServer.pump(); + + // New matrix from camera + _Scene->getCam().setTransformMode(NL3D::UTransformable::DirectMatrix); + _Scene->getCam().setMatrix (_MouseListener->getViewMatrix()); + + //nldebug("%s",_Scene->getCam().getMatrix().getPos().asString().c_str()); + } + + void CObjectViewerWidget::renderDriver() + { + // Render the scene. + if((NL3D::CBloomEffect::instance().getDriver() != NULL) && (_BloomEffect)) + { + NL3D::CBloomEffect::instance().initBloom(); + } + _Driver->clearBuffers(_BackgroundColor); + } + + void CObjectViewerWidget::renderScene() + { + // render the scene + _Scene->render(); + + if((NL3D::CBloomEffect::instance().getDriver() != NULL) && (_BloomEffect)) + { + NL3D::CBloomEffect::instance().endBloom(); + NL3D::CBloomEffect::instance().endInterfacesDisplayBloom(); + } + } + + void CObjectViewerWidget::renderDebug2D() + { + } + + void CObjectViewerWidget::saveScreenshot(const std::string &nameFile, bool jpg, bool png, bool tga) + { + //H_AUTO2 + + // FIXME: create screenshot path if it doesn't exist! + + // empty bitmap + CBitmap bitmap; + // copy the driver buffer to the bitmap + _Driver->getBuffer(bitmap); + // create the file name + string filename = std::string("./") + nameFile; + // write the bitmap as a jpg, png or tga to the file + if (jpg) + { + string newfilename = CFile::findNewFile(filename + ".jpg"); + COFile outputFile(newfilename); + bitmap.writeJPG(outputFile, 100); + nlinfo("Screenshot '%s' saved", newfilename.c_str()); + } + if (png) + { + string newfilename = CFile::findNewFile(filename + ".png"); + COFile outputFile(newfilename); + bitmap.writePNG(outputFile, 24); + nlinfo("Screenshot '%s' saved", newfilename.c_str()); + } + if (tga) + { + string newfilename = CFile::findNewFile(filename + ".tga"); + COFile outputFile(newfilename); + bitmap.writeTGA(outputFile, 24, false); + nlinfo("Screenshot '%s' saved", newfilename.c_str()); + } + } + + bool CObjectViewerWidget::loadMesh(const std::string &meshFileName, const std::string &skelFileName) + { + std::string fileName = CFile::getFilenameWithoutExtension(meshFileName); + if ( _Entities.count(fileName) != 0) + return false; + + CPath::addSearchPath(CFile::getPath(meshFileName), false, false); + + // create instance of the mesh character + UInstance Entity = _Scene->createInstance(meshFileName); + + CAABBox bbox; + Entity.getShapeAABBox(bbox); + setCamera(_Scene, bbox , Entity, true); + + _MouseListener->setMatrix(_Scene->getCam().getMatrix()); + + USkeleton Skeleton = _Scene->createSkeleton(skelFileName); + + // if we can't create entity, skip it + if (Entity.empty()) return false; + + // create a new entity + EIT eit = (_Entities.insert (make_pair (fileName, CEntity()))).first; + CEntity &entity = (*eit).second; + + // set the entity up + entity._Name = fileName; + entity._FileNameShape = meshFileName; + entity._FileNameSkeleton = skelFileName; + entity._Instance = Entity; + if (!Skeleton.empty()) + { + entity._Skeleton = Skeleton; + entity._Skeleton.bindSkin (entity._Instance); + } + entity._AnimationSet = _Driver->createAnimationSet(false); + entity._PlayList = _PlayListManager->createPlayList(entity._AnimationSet); + return true; + } + + void CObjectViewerWidget::setVisible(bool visible) + { + // called by show() + // code assuming visible window needed to init the 3d driver + nldebug("%d", visible); + if (visible) + { + QWidget::setVisible(true); + } + else + { + QWidget::setVisible(false); + } + } + + void CObjectViewerWidget::resetScene() + { + deleteEntities(); + + // Reset camera. + //.. + + // to load files with the same name but located in different directories + //CPath::clearMap(); + + // load and set search paths from config + //Modules::config().configSearchPaths(); + + _CurrentInstance = ""; + + nlinfo("Scene cleared"); + } + + void CObjectViewerWidget::setBackgroundColor(NLMISC::CRGBA backgroundColor) + { + _BackgroundColor = backgroundColor; + + // config file variable changes + //Modules::config().getConfigFile().getVar("BackgroundColor").setAsInt(_BackgroundColor.R, 0); + //Modules::config().getConfigFile().getVar("BackgroundColor").setAsInt(_BackgroundColor.G, 1); + //Modules::config().getConfigFile().getVar("BackgroundColor").setAsInt(_BackgroundColor.B, 2); + } + + void CObjectViewerWidget::setGraphicsDriver(bool Direct3D) + { + //_Direct3D = Direct3D; + + //if (_Direct3D) Modules::config().getConfigFile().getVar("GraphicsDriver").setAsString("Direct3D"); + //else Modules::config().getConfigFile().getVar("GraphicsDriver").setAsString("OpenGL"); + } + + void CObjectViewerWidget::setSizeViewport(uint16 w, uint16 h) + { + _Scene->getCam().setPerspective(_CameraFocal * (float)Pi/180.f, (float)w/h, 0.1f, 1000); + } + + void CObjectViewerWidget::setCurrentObject(const std::string &name) + { + if ((_Entities.count(name) != 0) || ( name.empty() )) _CurrentInstance = name; + else nlerror ("Entity %s not found", name.c_str()); + nlinfo("set current entity %s", _CurrentInstance.c_str()); + } + + CEntity& CObjectViewerWidget::getEntity(const std::string &name) + { + if ( _Entities.count(name) == 0) nlerror("Entity %s not found", name.c_str()); + EIT eit = _Entities.find (name); + return (*eit).second; + } + + void CObjectViewerWidget::getListObjects(std::vector &listObj) + { + listObj.clear(); + for (EIT eit = _Entities.begin(); eit != _Entities.end(); ++eit) + listObj.push_back((*eit).second._Name); + } + + void CObjectViewerWidget::deleteEntity(CEntity &entity) + { + if (entity._PlayList != NULL) + { + _PlayListManager->deletePlayList (entity._PlayList); + entity._PlayList = NULL; + } + + if (entity._AnimationSet != NULL) + { + _Driver->deleteAnimationSet(entity._AnimationSet); + entity._AnimationSet = NULL; + } + + if (!entity._Skeleton.empty()) + { + entity._Skeleton.detachSkeletonSon(entity._Instance); + + _Scene->deleteSkeleton(entity._Skeleton); + entity._Skeleton = NULL; + } + + if (!entity._Instance.empty()) + { + _Scene->deleteInstance(entity._Instance); + entity._Instance = NULL; + } + } + + void CObjectViewerWidget::deleteEntities() + { + for (EIT eit = _Entities.begin(); eit != _Entities.end(); ++eit) + { + CEntity &entity = (*eit).second; + deleteEntity(entity); + } + _Entities.clear(); + } + + void CObjectViewerWidget::setCamera(NL3D::UScene *scene, CAABBox &bbox, UTransform &entity, bool high_z) + { + CVector pos(0.f, 0.f, 0.f); + CQuat quat(0.f, 0.f, 0.f, 0.f); + NL3D::UInstance inst; + inst.cast(entity); + if (!inst.empty()) + { + inst.getDefaultPos(pos); + inst.getDefaultRotQuat(quat); + } + + // fix scale (some shapes have a different value) + entity.setScale(1.f, 1.f, 1.f); + + UCamera Camera = scene->getCam(); + CVector max_radius = bbox.getHalfSize(); + + CVector center = bbox.getCenter(); + entity.setPivot(center); + center += pos; + + //scene->getCam().setPerspective(_CameraFocal * (float)Pi/180.f, (float)w/h, 0.1f, 1000); + float fov = float(_CameraFocal * (float)Pi/180.0); + //Camera.setPerspective (fov, 1.0f, 0.1f, 1000.0f); + float radius = max(max(max_radius.x, max_radius.y), max_radius.z); + if (radius == 0.f) radius = 1.f; + float left, right, bottom, top, znear, zfar; + Camera.getFrustum(left, right, bottom, top, znear, zfar); + float dist = (radius / (tan(fov/2))) * 0.2; + CVector eye(center); + CVector ax(quat.getAxis()); + + if (ax.isNull() || ax == CVector::I) + { + ax = CVector::J; + } + else if (ax == -CVector::K) + { + ax = -CVector::J; + } + + eye -= ax * (dist+radius); + if (high_z) + eye.z += max_radius.z/1.0f; + Camera.lookAt(eye, center); + setupLight(eye, center - eye); + } + + bool CObjectViewerWidget::setupLight(const CVector &position, const CVector &direction) + { + if (!_Light) + _Light = ULight::createLight(); + if (!_Light) return false; + + // set mode of the light + _Light->setMode(ULight::DirectionalLight); + + // set position of the light + // Light->setupDirectional(settings.light_ambiant, settings.light_diffuse, settings.light_specular, settings.light_direction); + NLMISC::CRGBA light_ambiant = CRGBA(0,0,0); + NLMISC::CRGBA light_diffuse = CRGBA(255,255,255); + NLMISC::CRGBA light_specular = CRGBA(255,255,255); + NLMISC::CVector light_direction = CVector(0.25, 0.25, 0.25); + _Light->setupPointLight(light_ambiant, light_diffuse, light_specular, position, direction + light_direction); + + // set and enable the light + _Driver->setLight(0, *_Light); + _Driver->enableLight(0); + + return true; + } + + QIcon* CObjectViewerWidget::saveOneImage(string shapename) + { + int output_width = 128; + int output_height = 128; + + // Create a scene + NL3D::UScene* Scene = _Driver->createScene(true); + if (!Scene) return 0; + + // get scene camera + if (Scene->getCam().empty()) + { + nlwarning("can't get camera from scene"); + return 0; + } + + // add an entity to the scene + UInstance Entity = Scene->createInstance(shapename.c_str()); + + // if we can't create entity, skip it + if (Entity.empty()) + { + nlwarning("can't create instance from %s", shapename.c_str()); + return 0; + } + + // get AABox of Entity + CAABBox bbox; + Entity.getShapeAABBox(bbox); + setCamera(Scene, bbox , Entity, true); + Scene->getCam().setPerspective(_CameraFocal * (float)Pi/180.f, (float)output_width/output_height, 0.1f, 1000); + + string filename = CPath::standardizePath("") + toString("%s.%s", shapename.c_str(), "png"); + + // the background is white + _Driver->clearBuffers(); + + // render the scene + Scene->render(); + + CBitmap btm; + _Driver->getBuffer(btm); + + btm.resample(output_width, output_height); + + COFile fs; + + if (fs.open(filename)) + { + if (!btm.writePNG(fs, 24)) + { + nlwarning("can't save image to PNG"); + return 0; + } + } + else + { + nlwarning("can't create %s", "test.png"); + return 0; + } + fs.close(); + + QIcon *icon = new QIcon(QString(filename.c_str())); + //CFile::deleteFile(filename); + return icon; + } void CObjectViewerWidget::updateAnimatePS(uint64 deltaTime) { @@ -731,67 +731,67 @@ namespace NLQT lastTime += deltaTime; float fdelta = 0.001f * (float) (lastTime - firstTime); _Scene->animate ( fdelta); - } - -#if defined(NL_OS_WINDOWS) - - typedef bool (*winProc)(NL3D::IDriver *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); - - bool CObjectViewerWidget::winEvent(MSG * message, long * result) - { - if (getDriver() && getDriver()->isActive()) - { - NL3D::IDriver *driver = dynamic_cast(getDriver())->getDriver(); - if (driver) - { - winProc proc = (winProc)driver->getWindowProc(); - return proc(driver, message->hwnd, message->message, message->wParam, message->lParam); - } - } - - return false; - } - -#elif defined(NL_OS_MAC) - - typedef bool (*cocoaProc)(NL3D::IDriver*, const void* e); - - bool CObjectViewerWidget::macEvent(EventHandlerCallRef caller, EventRef event) - { - if(caller) - nlerror("You are using QtCarbon! Only QtCocoa supported, please upgrade Qt"); - - if (getDriver() && getDriver()->isActive()) - { - NL3D::IDriver *driver = dynamic_cast(getDriver())->getDriver(); - if (driver) - { - cocoaProc proc = (cocoaProc)driver->getWindowProc(); - return proc(driver, event); - } - } - - return false; - } - -#elif defined(NL_OS_UNIX) - - typedef bool (*x11Proc)(NL3D::IDriver *drv, XEvent *e); - - bool CObjectViewerWidget::x11Event(XEvent *event) - { - if (getDriver() && getDriver()->isActive()) - { - NL3D::IDriver *driver = dynamic_cast(getDriver())->getDriver(); - if (driver) - { - x11Proc proc = (x11Proc)driver->getWindowProc(); - return proc(driver, event); - } - } - - return false; - } -#endif - -} /* namespace NLQT */ + } + +#if defined(NL_OS_WINDOWS) + + typedef bool (*winProc)(NL3D::IDriver *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + + bool CObjectViewerWidget::winEvent(MSG * message, long * result) + { + if (getDriver() && getDriver()->isActive()) + { + NL3D::IDriver *driver = dynamic_cast(getDriver())->getDriver(); + if (driver) + { + winProc proc = (winProc)driver->getWindowProc(); + return proc(driver, message->hwnd, message->message, message->wParam, message->lParam); + } + } + + return false; + } + +#elif defined(NL_OS_MAC) + + typedef bool (*cocoaProc)(NL3D::IDriver*, const void* e); + + bool CObjectViewerWidget::macEvent(EventHandlerCallRef caller, EventRef event) + { + if(caller) + nlerror("You are using QtCarbon! Only QtCocoa supported, please upgrade Qt"); + + if (getDriver() && getDriver()->isActive()) + { + NL3D::IDriver *driver = dynamic_cast(getDriver())->getDriver(); + if (driver) + { + cocoaProc proc = (cocoaProc)driver->getWindowProc(); + return proc(driver, event); + } + } + + return false; + } + +#elif defined(NL_OS_UNIX) + + typedef bool (*x11Proc)(NL3D::IDriver *drv, XEvent *e); + + bool CObjectViewerWidget::x11Event(XEvent *event) + { + if (getDriver() && getDriver()->isActive()) + { + NL3D::IDriver *driver = dynamic_cast(getDriver())->getDriver(); + if (driver) + { + x11Proc proc = (x11Proc)driver->getWindowProc(); + return proc(driver, event); + } + } + + return false; + } +#endif + +} /* namespace NLQT */ diff --git a/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.h b/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.h index 15c9b0fa9..fb6656679 100644 --- a/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.h +++ b/code/nel/tools/3d/object_viewer_widget/src/object_viewer_widget.h @@ -1,229 +1,229 @@ -/* -Object Viewer Qt Widget -Copyright (C) 2010 Adrian Jaekel - -This program 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 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 General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#ifndef OBJECT_VIEWER_WIDGET_H -#define OBJECT_VIEWER_WIDGET_H - -// STL includes - -// Qt includes -#include -#include - -// NeL includes -#include -#include - -// Project includes -#include "entity.h" -#include "interfaces.h" - -namespace NL3D -{ - class UDriver; - class UScene; - class ULight; - class UInstance; - class UCamera; - class USkeleton; - class UPlayListManager; - class U3dMouseListener; -} - -class QIcon; -/** -namespace NLQT -@brief namespace NLQT -*/ -namespace NLQT -{ - class CObjectViewerWidget: - public QWidget, - public IObjectViewer - { - Q_OBJECT - Q_INTERFACES(NLQT::IObjectViewer) - - public: - /// Default constructor. - CObjectViewerWidget(QWidget *parent = 0); - virtual ~CObjectViewerWidget(); - - virtual QPaintEngine* paintEngine() const { return NULL; } - virtual void showEvent ( QShowEvent * event ); - - void setNelContext(NLMISC::INelContext &nelContext); - - static CObjectViewerWidget &objViewWid() { return *_objectViewerWidget; } - - /// Init a driver and create scene. - void init(); - - /// Release class. - void release(); - - /// Update mouse and keyboard events. And update camera matrix. - void updateInput(); - - /// Render Driver (clear all buffers and set background color). - void renderDriver(); - - /// Render current scene. - void renderScene(); - - /// Render Debug 2D (stuff for dev). - void renderDebug2D(); - - /// Make a screenshot of the current scene and save. - void saveScreenshot(const std::string &nameFile, bool jpg, bool png, bool tga); - - /// Load a mesh or particle system and add to current scene. - /// @param meshFileName - name loading shape or ps file. - /// @param skelFileName - name loading skeletin file. - /// @return true if file have been loaded, false if file have not been loaded. - bool loadMesh (const std::string &meshFileName, const std::string &skelFileName); - - /// Reset current scene. - void resetScene(); - - /// Set the background color. - /// @param backgroundColor - background color. - void setBackgroundColor(NLMISC::CRGBA backgroundColor); - - /// Set type driver. - /// @param Direct3D - type driver (true - Direct3D) or (false -OpenGL) - void setGraphicsDriver(bool Direct3D); - - /// Set size viewport for correct set perspective - /// @param w - width window. - /// @param h - height window. - void setSizeViewport(uint16 w, uint16 h); - - void setBloomEffect(bool enabled) { _BloomEffect = enabled; } - - /// Select instance from the scene - /// @param name - name instance, "" if no instance edited - void setCurrentObject(const std::string &name); - - /// Get current instance from the scene - /// @return name current instance, "" if no instance edited - const std::string& getCurrentObject() { return _CurrentInstance; } - - /// Get entity from the scene - /// @return ref Entity - CEntity& getEntity(const std::string &name); - - /// Get full list instances from the scene - /// @param listObj - ref of return list instances - void getListObjects(std::vector &listObj); - - /// Get value background color. - /// @return background color. - NLMISC::CRGBA getBackgroundColor() { return _BackgroundColor; } - - /// Get type driver. - /// @return true if have used Direct3D driver, false OpenGL driver. - inline bool getDirect3D() { return _Direct3D; } - - inline bool getBloomEffect() const { return _BloomEffect; } - - /// Get a pointer to the driver. - /// @return pointer to the driver. - inline NL3D::UDriver *getDriver() { return _Driver; } - - /// Get a pointer to the scene. - /// @return pointer to the scene. - inline NL3D::UScene *getScene() { return _Scene; } - - /// Get a manager of playlist - /// @return pointer to the UPlayListManager - inline NL3D::UPlayListManager *getPlayListManager() { return _PlayListManager; } - - void setCamera(NL3D::UScene *scene, NLMISC::CAABBox &bbox, NL3D::UTransform &entity, bool high_z=false); - bool setupLight(const NLMISC::CVector &position, const NLMISC::CVector &direction); - - QIcon* saveOneImage(std::string shapename); - - virtual void setVisible(bool visible); - - QWidget* getWidget() {return this;} - - virtual QString name() const {return ("ObjectViewerWidget");} - - protected: -#if defined(NL_OS_WINDOWS) - virtual bool winEvent(MSG * message, long * result); -#elif defined(NL_OS_MAC) - virtual bool macEvent(EventHandlerCallRef caller, EventRef event); -#elif defined(NL_OS_UNIX) - virtual bool x11Event(XEvent *event); -#endif - - private Q_SLOTS: - void updateRender(); - - private: +/* +Object Viewer Qt Widget +Copyright (C) 2010 Adrian Jaekel + +This program 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 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef OBJECT_VIEWER_WIDGET_H +#define OBJECT_VIEWER_WIDGET_H + +// STL includes + +// Qt includes +#include +#include + +// NeL includes +#include +#include + +// Project includes +#include "entity.h" +#include "interfaces.h" + +namespace NL3D +{ + class UDriver; + class UScene; + class ULight; + class UInstance; + class UCamera; + class USkeleton; + class UPlayListManager; + class U3dMouseListener; +} + +class QIcon; +/** +namespace NLQT +@brief namespace NLQT +*/ +namespace NLQT +{ + class CObjectViewerWidget: + public QWidget, + public IObjectViewer + { + Q_OBJECT + Q_INTERFACES(NLQT::IObjectViewer) + + public: + /// Default constructor. + CObjectViewerWidget(QWidget *parent = 0); + virtual ~CObjectViewerWidget(); + + virtual QPaintEngine* paintEngine() const { return NULL; } + virtual void showEvent ( QShowEvent * event ); + + void setNelContext(NLMISC::INelContext &nelContext); + + static CObjectViewerWidget &objViewWid() { return *_objectViewerWidget; } + + /// Init a driver and create scene. + void init(); + + /// Release class. + void release(); + + /// Update mouse and keyboard events. And update camera matrix. + void updateInput(); + + /// Render Driver (clear all buffers and set background color). + void renderDriver(); + + /// Render current scene. + void renderScene(); + + /// Render Debug 2D (stuff for dev). + void renderDebug2D(); + + /// Make a screenshot of the current scene and save. + void saveScreenshot(const std::string &nameFile, bool jpg, bool png, bool tga); + + /// Load a mesh or particle system and add to current scene. + /// @param meshFileName - name loading shape or ps file. + /// @param skelFileName - name loading skeletin file. + /// @return true if file have been loaded, false if file have not been loaded. + bool loadMesh (const std::string &meshFileName, const std::string &skelFileName); + + /// Reset current scene. + void resetScene(); + + /// Set the background color. + /// @param backgroundColor - background color. + void setBackgroundColor(NLMISC::CRGBA backgroundColor); + + /// Set type driver. + /// @param Direct3D - type driver (true - Direct3D) or (false -OpenGL) + void setGraphicsDriver(bool Direct3D); + + /// Set size viewport for correct set perspective + /// @param w - width window. + /// @param h - height window. + void setSizeViewport(uint16 w, uint16 h); + + void setBloomEffect(bool enabled) { _BloomEffect = enabled; } + + /// Select instance from the scene + /// @param name - name instance, "" if no instance edited + void setCurrentObject(const std::string &name); + + /// Get current instance from the scene + /// @return name current instance, "" if no instance edited + const std::string& getCurrentObject() { return _CurrentInstance; } + + /// Get entity from the scene + /// @return ref Entity + CEntity& getEntity(const std::string &name); + + /// Get full list instances from the scene + /// @param listObj - ref of return list instances + void getListObjects(std::vector &listObj); + + /// Get value background color. + /// @return background color. + NLMISC::CRGBA getBackgroundColor() { return _BackgroundColor; } + + /// Get type driver. + /// @return true if have used Direct3D driver, false OpenGL driver. + inline bool getDirect3D() { return _Direct3D; } + + inline bool getBloomEffect() const { return _BloomEffect; } + + /// Get a pointer to the driver. + /// @return pointer to the driver. + inline NL3D::UDriver *getDriver() { return _Driver; } + + /// Get a pointer to the scene. + /// @return pointer to the scene. + inline NL3D::UScene *getScene() { return _Scene; } + + /// Get a manager of playlist + /// @return pointer to the UPlayListManager + inline NL3D::UPlayListManager *getPlayListManager() { return _PlayListManager; } + + void setCamera(NL3D::UScene *scene, NLMISC::CAABBox &bbox, NL3D::UTransform &entity, bool high_z=false); + bool setupLight(const NLMISC::CVector &position, const NLMISC::CVector &direction); + + QIcon* saveOneImage(std::string shapename); + + virtual void setVisible(bool visible); + + QWidget* getWidget() {return this;} + + virtual QString name() const {return ("ObjectViewerWidget");} + + protected: +#if defined(NL_OS_WINDOWS) + virtual bool winEvent(MSG * message, long * result); +#elif defined(NL_OS_MAC) + virtual bool macEvent(EventHandlerCallRef caller, EventRef event); +#elif defined(NL_OS_UNIX) + virtual bool x11Event(XEvent *event); +#endif + + private Q_SLOTS: + void updateRender(); + + private: /// Update the animation time for Particle System animation. /// @param deltaTime - set the manual animation time. - void updateAnimatePS(uint64 deltaTime = 0); - - static CObjectViewerWidget *_objectViewerWidget; - - NLMISC::CLibraryContext *_LibContext; - - // render stuff - QTimer *_mainTimer; - bool _isGraphicsInitialized, _isGraphicsEnabled; - - void updateInitialization(bool visible); - - void deleteEntity (CEntity &entity); - - /// Delete all entities - void deleteEntities(); - - NLMISC::CRGBA _BackgroundColor; - - NL3D::UDriver *_Driver; - NL3D::UScene *_Scene; - NL3D::UPlayListManager *_PlayListManager; - NL3D::ULight *_Light; - NL3D::UCamera *_Camera; - NL3D::U3dMouseListener *_MouseListener; - - // The entities storage - CEntities _Entities; - - /// Camera parameters. - float _phi, _psi, _dist; - float _CameraFocal; - - bool _Direct3D; - bool _BloomEffect; - - std::string _CurrentInstance; - - // a temporary solution, and later remove - friend class CAnimationSetDialog; - - };/* class CObjectViewerWidget */ - -} /* namespace NLQT */ - -#endif // OBJECT_VIEWER_WIDGET_H + void updateAnimatePS(uint64 deltaTime = 0); + + static CObjectViewerWidget *_objectViewerWidget; + + NLMISC::CLibraryContext *_LibContext; + + // render stuff + QTimer *_mainTimer; + bool _isGraphicsInitialized, _isGraphicsEnabled; + + void updateInitialization(bool visible); + + void deleteEntity (CEntity &entity); + + /// Delete all entities + void deleteEntities(); + + NLMISC::CRGBA _BackgroundColor; + + NL3D::UDriver *_Driver; + NL3D::UScene *_Scene; + NL3D::UPlayListManager *_PlayListManager; + NL3D::ULight *_Light; + NL3D::UCamera *_Camera; + NL3D::U3dMouseListener *_MouseListener; + + // The entities storage + CEntities _Entities; + + /// Camera parameters. + float _phi, _psi, _dist; + float _CameraFocal; + + bool _Direct3D; + bool _BloomEffect; + + std::string _CurrentInstance; + + // a temporary solution, and later remove + friend class CAnimationSetDialog; + + };/* class CObjectViewerWidget */ + +} /* namespace NLQT */ + +#endif // OBJECT_VIEWER_WIDGET_H diff --git a/code/nel/tools/3d/object_viewer_widget/src/stdpch.cpp b/code/nel/tools/3d/object_viewer_widget/src/stdpch.cpp index e5875aca1..3dd66d085 100644 --- a/code/nel/tools/3d/object_viewer_widget/src/stdpch.cpp +++ b/code/nel/tools/3d/object_viewer_widget/src/stdpch.cpp @@ -1,5 +1,5 @@ /* -Object Viewer Qt Widget +Object Viewer Qt Widget Copyright (C) 2010 Adrian Jaekel This program is free software: you can redistribute it and/or modify diff --git a/code/nel/tools/3d/s3tc_compressor_lib/s3tc_compressor.cpp b/code/nel/tools/3d/s3tc_compressor_lib/s3tc_compressor.cpp index 0d2ea6a7e..9d6506197 100644 --- a/code/nel/tools/3d/s3tc_compressor_lib/s3tc_compressor.cpp +++ b/code/nel/tools/3d/s3tc_compressor_lib/s3tc_compressor.cpp @@ -42,15 +42,15 @@ static void compressMipMap(uint8 *pixSrc, sint width, sint height, vector +// 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 . + +#include +#include "camera.h" + +#include + +#include "global.h" +#include "misc.h" + +using namespace NLMISC; +using namespace NL3D; + +//--------------------------------------------------- +// update the camera perspective setup +//--------------------------------------------------- +void updateCameraPerspective() +{ + float fov, aspectRatio; + computeCurrentFovAspectRatio(fov, aspectRatio); + + // change the perspective of the scene + if(!MainCam.empty()) + MainCam.setPerspective(fov, aspectRatio, CameraSetupZNear, ClientCfg.Vision); + // change the perspective of the root scene + if(SceneRoot) + { + UCamera cam= SceneRoot->getCam(); + cam.setPerspective(fov, aspectRatio, SceneRootCameraZNear, SceneRootCameraZFar); + } +} + +void buildCameraClippingPyramid(std::vector &planes) +{ + if (StereoDisplay) StereoDisplay->getClippingFrustum(0, &MainCam); + + // Compute pyramid in view basis. + CVector pfoc(0,0,0); + const CFrustum &frustum = MainCam.getFrustum(); + InvMainSceneViewMatrix = MainCam.getMatrix(); + MainSceneViewMatrix = InvMainSceneViewMatrix; + MainSceneViewMatrix.invert(); + + CVector lb(frustum.Left, frustum.Near, frustum.Bottom ); + CVector lt(frustum.Left, frustum.Near, frustum.Top ); + CVector rb(frustum.Right, frustum.Near, frustum.Bottom ); + CVector rt(frustum.Right, frustum.Near, frustum.Top ); + + CVector lbFar(frustum.Left, ClientCfg.CharacterFarClip, frustum.Bottom); + CVector ltFar(frustum.Left, ClientCfg.CharacterFarClip, frustum.Top ); + CVector rtFar(frustum.Right, ClientCfg.CharacterFarClip, frustum.Top ); + + planes.resize (4); + // planes[0].make(lbFar, ltFar, rtFar); + planes[0].make(pfoc, lt, lb); + planes[1].make(pfoc, rt, lt); + planes[2].make(pfoc, rb, rt); + planes[3].make(pfoc, lb, rb); + + // Compute pyramid in World basis. + // The vector transformation M of a plane p is computed as p*M-1. + // Here, ViewMatrix== CamMatrix-1. Hence the following formula. + uint i; + + for (i = 0; i < 4; i++) + { + planes[i] = planes[i]*MainSceneViewMatrix; + } +} + +/* end of file */ \ No newline at end of file diff --git a/code/nel/src/3d/driver/opengl3/driver_glsl_vertex_program.h b/code/ryzom/client/src/camera.h similarity index 67% rename from code/nel/src/3d/driver/opengl3/driver_glsl_vertex_program.h rename to code/ryzom/client/src/camera.h index 49f443641..037661c3a 100644 --- a/code/nel/src/3d/driver/opengl3/driver_glsl_vertex_program.h +++ b/code/ryzom/client/src/camera.h @@ -1,37 +1,29 @@ -// NeL - MMORPG Framework -// 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 . - - -#ifndef GLSL_VERTEX_PROGRAM_H -#define GLSL_VERTEX_PROGRAM_H - -#include "driver_glsl_program.h" -#include - -namespace NL3D -{ - class CGLSLVertexProgram : public CGLSLProgram - { - public: - CGLSLVertexProgram(); - ~CGLSLVertexProgram(); - }; -} - -#endif - - - +// Ryzom - MMORPG Framework +// 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 . + +#ifndef CL_CAMERA_H +#define CL_CAMERA_H + +#include + +#include + +void updateCameraPerspective(); +void buildCameraClippingPyramid(std::vector &planes); + +#endif // CL_CAMERA_H + +/* end of file */ diff --git a/code/ryzom/client/src/character_cl.cpp b/code/ryzom/client/src/character_cl.cpp index e3b453cfc..932819817 100644 --- a/code/ryzom/client/src/character_cl.cpp +++ b/code/ryzom/client/src/character_cl.cpp @@ -488,7 +488,7 @@ void CCharacterCL::stopAttachedFXForCurrrentAnim(bool stopLoopingFX) { if(!(*tmpItAttached)->FX.empty()) { - if (!(*tmpItAttached)->FX.removeByID('STOP') && !(*tmpItAttached)->FX.removeByID('main')) + if (!(*tmpItAttached)->FX.removeByID(NELID("STOP")) && !(*tmpItAttached)->FX.removeByID(NELID("main"))) { (*tmpItAttached)->FX.activateEmitters(false); } @@ -9373,7 +9373,7 @@ void CCharacterCL::CWornItem::enableAdvantageFX(NL3D::UInstance parent) if (!enabled) { // well, it is unlikely that player will loses its ability to master an item after he gained it, but manage the case anyway. - if (!AdvantageFX.removeByID('STOP') && !AdvantageFX.removeByID('main')) + if (!AdvantageFX.removeByID(NELID("STOP")) && !AdvantageFX.removeByID(NELID("main"))) { AdvantageFX.activateEmitters(false); } diff --git a/code/ryzom/client/src/client_cfg.cpp b/code/ryzom/client/src/client_cfg.cpp index 5331dac2c..37fd81a72 100644 --- a/code/ryzom/client/src/client_cfg.cpp +++ b/code/ryzom/client/src/client_cfg.cpp @@ -302,6 +302,10 @@ CClientConfig::CClientConfig() Contrast = 0.f; // Default Monitor Contrast. Luminosity = 0.f; // Default Monitor Luminosity. Gamma = 0.f; // Default Monitor Gamma. + + VREnable = false; + VRDisplayDevice = "Auto"; + VRDisplayDeviceId = ""; Local = false; // Default is Net Mode. FSHost = ""; // Default Host. @@ -848,6 +852,9 @@ void CClientConfig::setValues() else cfgWarning ("Default value used for 'Driver3D' !!!"); + READ_BOOL_FV(VREnable) + READ_STRING_FV(VRDisplayDevice) + READ_STRING_FV(VRDisplayDeviceId) //////////// // INPUTS // diff --git a/code/ryzom/client/src/client_cfg.h b/code/ryzom/client/src/client_cfg.h index 265894bf8..de5700ed1 100644 --- a/code/ryzom/client/src/client_cfg.h +++ b/code/ryzom/client/src/client_cfg.h @@ -146,6 +146,11 @@ struct CClientConfig /// Monitor Gamma [-1 ~ 1], default 0 float Gamma; + // VR + bool VREnable; + std::string VRDisplayDevice; + std::string VRDisplayDeviceId; + /// Client in Local mode or not. bool Local; /// Host. diff --git a/code/ryzom/client/src/decal.cpp b/code/ryzom/client/src/decal.cpp index 45c5311ac..1454d9f59 100644 --- a/code/ryzom/client/src/decal.cpp +++ b/code/ryzom/client/src/decal.cpp @@ -84,7 +84,65 @@ static const char *DecalAttenuationVertexProgramCode = MUL o[COL0].w, v[3], R0.w; \n\ END \n"; -static NL3D::CVertexProgram DecalAttenuationVertexProgram(DecalAttenuationVertexProgramCode); +class CVertexProgramDecalAttenuation : public CVertexProgram +{ +public: + struct CIdx + { + // 0-3 mvp + uint WorldToUV0; // 4 + uint WorldToUV1; // 5 + uint RefCamDist; // 6 + uint DistScaleBias; // 7 + uint Diffuse; // 8 + // 9 + // 10 + uint BlendScale; // 11 + }; + CVertexProgramDecalAttenuation() + { + // nelvp + { + CSource *source = new CSource(); + source->Profile = nelvp; + source->DisplayName = "nelvp/DecalAttenuation"; + source->setSourcePtr(DecalAttenuationVertexProgramCode); + source->ParamIndices["modelViewProjection"] = 0; + source->ParamIndices["worldToUV0"] = 4; + source->ParamIndices["worldToUV1"] = 5; + source->ParamIndices["refCamDist"] = 6; + source->ParamIndices["distScaleBias"] = 7; + source->ParamIndices["diffuse"] = 8; + source->ParamIndices["blendScale"] = 11; + addSource(source); + } + // TODO_VP_GLSL + } + ~CVertexProgramDecalAttenuation() + { + + } + virtual void buildInfo() + { + m_Idx.WorldToUV0 = getUniformIndex("worldToUV0"); + nlassert(m_Idx.WorldToUV0 != ~0); + m_Idx.WorldToUV1 = getUniformIndex("worldToUV1"); + nlassert(m_Idx.WorldToUV1 != ~0); + m_Idx.RefCamDist = getUniformIndex("refCamDist"); + nlassert(m_Idx.RefCamDist != ~0); + m_Idx.DistScaleBias = getUniformIndex("distScaleBias"); + nlassert(m_Idx.DistScaleBias != ~0); + m_Idx.Diffuse = getUniformIndex("diffuse"); + nlassert(m_Idx.Diffuse != ~0); + m_Idx.BlendScale = getUniformIndex("blendScale"); + nlassert(m_Idx.BlendScale != ~0); + } + inline const CIdx &idx() const { return m_Idx; } +private: + CIdx m_Idx; +}; + +static NLMISC::CSmartPtr DecalAttenuationVertexProgram; typedef CShadowPolyReceiver::CRGBAVertex CRGBAVertex; @@ -92,6 +150,10 @@ typedef CShadowPolyReceiver::CRGBAVertex CRGBAVertex; // **************************************************************************** CDecal::CDecal() { + if (!DecalAttenuationVertexProgram) + { + DecalAttenuationVertexProgram = new CVertexProgramDecalAttenuation(); + } _ShadowMap = new CShadowMap(&(((CSceneUser *) Scene)->getScene().getRenderTrav().getShadowMapManager())); _Material.initUnlit(); _Diffuse = CRGBA::White; @@ -303,6 +365,7 @@ void CDecal::renderTriCache(NL3D::IDriver &drv, NL3D::CShadowPolyReceiver &/* drv.setupModelMatrix(modelMat); if (useVertexProgram) { + CVertexProgramDecalAttenuation *program = DecalAttenuationVertexProgram; { CVertexBufferReadWrite vba; _VB.setNumVertices((uint32)_TriCache.size()); @@ -310,16 +373,16 @@ void CDecal::renderTriCache(NL3D::IDriver &drv, NL3D::CShadowPolyReceiver &/* memcpy(vba.getVertexCoordPointer(), &_TriCache[0], sizeof(CRGBAVertex) * _TriCache.size()); } drv.activeVertexBuffer(_VB); - drv.setConstantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); - drv.setConstant(4, _WorldToUVMatrix[0][0], _WorldToUVMatrix[1][0], _WorldToUVMatrix[2][0], _WorldToUVMatrix[3][0]); - drv.setConstant(5, _WorldToUVMatrix[0][1], _WorldToUVMatrix[1][1], _WorldToUVMatrix[2][1], _WorldToUVMatrix[3][1]); - drv.setConstant(8, _Diffuse.R * (1.f / 255.f), _Diffuse.G * (1.f / 255.f), _Diffuse.B * (1.f / 255.f), 1.f); + drv.setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CProgramIndex::ModelViewProjection), NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); + drv.setUniform4f(IDriver::VertexProgram, program->idx().WorldToUV0, _WorldToUVMatrix[0][0], _WorldToUVMatrix[1][0], _WorldToUVMatrix[2][0], _WorldToUVMatrix[3][0]); + drv.setUniform4f(IDriver::VertexProgram, program->idx().WorldToUV1, _WorldToUVMatrix[0][1], _WorldToUVMatrix[1][1], _WorldToUVMatrix[2][1], _WorldToUVMatrix[3][1]); + drv.setUniform4f(IDriver::VertexProgram, program->idx().Diffuse, _Diffuse.R * (1.f / 255.f), _Diffuse.G * (1.f / 255.f), _Diffuse.B * (1.f / 255.f), 1.f); const NLMISC::CVector &camPos = MainCam.getMatrix().getPos(); - drv.setConstant(6, camPos.x - _RefPosition.x, camPos.y - _RefPosition.y, camPos.z - _RefPosition.z, 1.f); + drv.setUniform4f(IDriver::VertexProgram, program->idx().RefCamDist, camPos.x - _RefPosition.x, camPos.y - _RefPosition.y, camPos.z - _RefPosition.z, 1.f); // bottom & top blend float bottomBlendScale = 1.f / favoid0(_BottomBlendZMax - _BottomBlendZMin); float topBlendScale = 1.f / favoid0(_TopBlendZMin - _TopBlendZMax); - drv.setConstant(11, bottomBlendScale, bottomBlendScale * (_RefPosition.z - _BottomBlendZMin), + drv.setUniform4f(IDriver::VertexProgram, program->idx().BlendScale, bottomBlendScale, bottomBlendScale * (_RefPosition.z - _BottomBlendZMin), topBlendScale, topBlendScale * (_RefPosition.z - _TopBlendZMax)); // static volatile bool wantSimpleMat = false; @@ -560,12 +623,12 @@ void CDecalRenderList::renderAllDecals() NL3D::IDriver *drvInternal = ((CDriverUser *) Driver)->getDriver(); // static volatile bool forceNoVertexProgram = false; - if (drvInternal->isVertexProgramSupported() && !forceNoVertexProgram) + if (!forceNoVertexProgram && drvInternal->compileVertexProgram(DecalAttenuationVertexProgram)) { - //drvInternal->setConstantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); - drvInternal->setConstant(7, _DistScale, _DistBias, 0.f, 1.f); + drvInternal->activeVertexProgram(DecalAttenuationVertexProgram); + //drvInternal->setCons/tantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); + drvInternal->setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram->idx().DistScaleBias, _DistScale, _DistBias, 0.f, 1.f); useVertexProgram = true; - drvInternal->activeVertexProgram(&DecalAttenuationVertexProgram); } else { diff --git a/code/ryzom/client/src/fx_cl.cpp b/code/ryzom/client/src/fx_cl.cpp index 971100386..7a5418c3a 100644 --- a/code/ryzom/client/src/fx_cl.cpp +++ b/code/ryzom/client/src/fx_cl.cpp @@ -263,7 +263,7 @@ CFxCL::~CFxCL() // Stop emitters UParticleSystemInstance fxInst; fxInst.cast (_Instance); - if (!fxInst.removeByID( 'STOP' ) && !fxInst.removeByID( 'main' ) ) + if (!fxInst.removeByID(NELID("STOP")) && !fxInst.removeByID(NELID("main"))) { fxInst.activateEmitters( false ); } diff --git a/code/ryzom/client/src/fx_manager.h b/code/ryzom/client/src/fx_manager.h index 71df3f2c4..e41171e9e 100644 --- a/code/ryzom/client/src/fx_manager.h +++ b/code/ryzom/client/src/fx_manager.h @@ -77,7 +77,7 @@ protected: float TimeOut; bool TestNoMoreParticles; public: - CFX2Remove(NL3D::UParticleSystemInstance instance=NL3D::UParticleSystemInstance(), float timeOut = NULL, bool testNoMoreParticles = false) + CFX2Remove(NL3D::UParticleSystemInstance instance=NL3D::UParticleSystemInstance(), float timeOut = 0.f, bool testNoMoreParticles = false) { Instance = instance; TimeOut = timeOut; diff --git a/code/ryzom/client/src/global.cpp b/code/ryzom/client/src/global.cpp index 8bd6f10fa..2e3ba875a 100644 --- a/code/ryzom/client/src/global.cpp +++ b/code/ryzom/client/src/global.cpp @@ -26,6 +26,8 @@ using namespace NLMISC; // *************************************************************************** // Main System NL3D::UDriver *Driver = 0; // The main 3D Driver +NL3D::IStereoDisplay *StereoDisplay = NULL; // Stereo display +NL3D::IStereoHMD *StereoHMD = NULL; // Head mount display CSoundManager *SoundMngr = 0; // the sound manager NL3D::UMaterial GenericMat; // Generic Material NL3D::UTextContext *TextContext = 0; // Context for all the text in the client. diff --git a/code/ryzom/client/src/global.h b/code/ryzom/client/src/global.h index a6b7a03c6..9e5a294ae 100644 --- a/code/ryzom/client/src/global.h +++ b/code/ryzom/client/src/global.h @@ -40,6 +40,8 @@ namespace NL3D class UMaterial; class UTextContext; class UWaterEnvMap; + class IStereoDisplay; + class IStereoHMD; } class CEntityAnimationManager; @@ -77,6 +79,8 @@ const float ExtraZoneLoadingVision = 100.f; // *************************************************************************** // Main System extern NL3D::UDriver *Driver; // The main 3D Driver +extern NL3D::IStereoDisplay *StereoDisplay; // Stereo display +extern NL3D::IStereoHMD *StereoHMD; // Head mount display extern CSoundManager *SoundMngr; // the sound manager extern NL3D::UMaterial GenericMat; // Generic Material extern NL3D::UTextContext *TextContext; // Context for all the text in the client. diff --git a/code/ryzom/client/src/hair_set.cpp b/code/ryzom/client/src/hair_set.cpp index 1bc6f030c..d82733162 100644 --- a/code/ryzom/client/src/hair_set.cpp +++ b/code/ryzom/client/src/hair_set.cpp @@ -47,8 +47,8 @@ void CHairSet::init (NLMISC::IProgressCallback &progress) const CItemSheet *item = SheetMngr.getItem(SLOTTYPE::HEAD_SLOT, k); if( (item) && (!item->getShape().empty()) ) { - std::string itemName = item->getShape(); - itemName = NLMISC::strlwr(itemName); + std::string itemName = NLMISC::toLower(item->getShape()); + if (item->getShape().find("cheveux", 0) != std::string::npos) { // get race diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 4a9392d34..c9b74585a 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -39,6 +39,7 @@ #include "nel/3d/u_driver.h" #include "nel/3d/u_text_context.h" #include "nel/3d/u_shape_bank.h" +#include "nel/3d/stereo_hmd.h" // Net. #include "nel/net/email.h" // Ligo. @@ -46,6 +47,7 @@ // Std. #include +#include // Game Share #include "game_share/ryzom_version.h" // Client @@ -792,6 +794,59 @@ void prelogInit() // Check driver version checkDriverVersion(); + // Initialize the VR devices (even more important than the most important part of the client) + nmsg = "Initializing VR devices..."; + ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) ); + if (ClientCfg.VREnable) + { + nldebug("VR [C]: Enabled"); + std::vector devices; + IStereoDisplay::listDevices(devices); + for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) + { + std::stringstream name; + name << std::string("[") << it->Serial << "] [" << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName << "]"; + nlinfo("VR [C]: Stereo Display: %s", name.str().c_str()); + } + CStereoDeviceInfo *deviceInfo = NULL; + if (ClientCfg.VRDisplayDevice == std::string("Auto") + && devices.begin() != devices.end()) + { + deviceInfo = &devices[0]; + } + else + { + for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) + { + std::stringstream name; + name << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName; + if (name.str() == ClientCfg.VRDisplayDevice) + deviceInfo = &(*it); + if (ClientCfg.VRDisplayDeviceId == it->Serial) + break; + } + } + if (deviceInfo) + { + nlinfo("VR [C]: Create VR stereo display device"); + StereoDisplay = IStereoDisplay::createDevice(*deviceInfo); + if (StereoDisplay) + { + if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD) + { + nlinfo("VR [C]: Stereo display device is a HMD"); + StereoHMD = static_cast(StereoDisplay); + } + } + } + } + else + { + nldebug("VR [C]: NOT Enabled"); + } + IStereoDisplay::releaseUnusedLibraries(); + + // Create the driver (most important part of the client). nmsg = "Creating 3d driver..."; ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) ); @@ -863,6 +918,11 @@ void prelogInit() Driver->setSwapVBLInterval(1); else Driver->setSwapVBLInterval(0); + + if (StereoDisplay) + { + // override mode TODO + } // Set the mode of the window. if (!Driver->setDisplay (mode, false)) @@ -1105,6 +1165,12 @@ void prelogInit() // init bloom effect CBloomEffect::getInstance().init(driver != UDriver::Direct3d); + + if (StereoDisplay) + { + // Init stereo display resources + StereoDisplay->setDriver(Driver); + } nlinfo ("PROFILE: %d seconds for prelogInit", (uint32)(ryzomGetLocalTime ()-initStart)/1000); diff --git a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp index 54c8b6fac..688c27635 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_misc.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_misc.cpp @@ -542,10 +542,12 @@ void renderSceneScreenShot (uint left, uint right, uint top, uint bottom, uint s { CCameraBackup cbScene = setupCameraForScreenshot(*Scene, left, right, top, bottom, screenShotWidth, screenShotHeight); CCameraBackup cbCanopy = setupCameraForScreenshot(*SceneRoot, left, right, top, bottom, screenShotWidth, screenShotHeight); + commitCamera(); // sky setup are copied from main scene before rendering so no setup done here - renderAll(ClientCfg.ScreenShotFullDetail); + renderScene(ClientCfg.ScreenShotFullDetail, ClientCfg.Bloom); restoreCamera(*Scene, cbScene); restoreCamera(*SceneRoot, cbCanopy); + commitCamera(); } // *************************************************************************** diff --git a/code/ryzom/client/src/interface_v3/animal_position_state.cpp b/code/ryzom/client/src/interface_v3/animal_position_state.cpp index 9789d4012..50e6d4265 100644 --- a/code/ryzom/client/src/interface_v3/animal_position_state.cpp +++ b/code/ryzom/client/src/interface_v3/animal_position_state.cpp @@ -64,7 +64,7 @@ bool CPositionState::getPos(sint32 &px, sint32 &py) // *************************************************************************** void CPositionState::serialNodeLeaf(NLMISC::IStream &f, CCDBNodeLeaf *&dbNode) { - f.serialCheck((uint32) 'NL__'); + f.serialCheck(NELID("NL__")); f.serialVersion(0); std::string dbPath; if (f.isReading()) @@ -85,18 +85,18 @@ void CPositionState::serialNodeLeaf(NLMISC::IStream &f, CCDBNodeLeaf *&dbNode) } f.serial(dbPath); } - f.serialCheck((uint32) 'END_'); + f.serialCheck(NELID("END_")); } // *************************************************************************** void CUIDEntityPositionState::serial(NLMISC::IStream &f) { - f.serialCheck((uint32) 'UIDE'); + f.serialCheck(NELID("UIDE")); f.serialVersion(0); serialNodeLeaf(f, _DBPos); serialNodeLeaf(f, _Uid); - f.serialCheck((uint32) '_END'); + f.serialCheck(NELID("_END")); } // *************************************************************************** @@ -241,11 +241,11 @@ bool CAnimalPositionState::getPos(sint32 &px, sint32 &py) // *************************************************************************** void CAnimalPositionState::serial(NLMISC::IStream &f) { - f.serialCheck((uint32) 'APS_'); + f.serialCheck(NELID("APS_")); f.serialVersion(0); CUIDEntityPositionState::serial(f); serialNodeLeaf(f, _Status); - f.serialCheck((uint32) 'END_'); + f.serialCheck(NELID("END_")); } @@ -257,7 +257,7 @@ void CAnimalPositionState::serial(NLMISC::IStream &f) // *************************************************************************** CEntityCL *CNamedEntityPositionState::getEntity() { - if (!dbOk()) return false; + if (!dbOk()) return NULL; return EntitiesMngr.getEntityByName(_Name->getValue32()); } @@ -299,11 +299,11 @@ bool CDialogEntityPositionState::getDbPos(sint32 &px, sint32 &py) // *************************************************************************** void CNamedEntityPositionState::serial(NLMISC::IStream &f) { - f.serialCheck((uint32) 'NEPS'); + f.serialCheck(NELID("NEPS")); f.serialVersion(0); serialNodeLeaf(f, _Name); serialNodeLeaf(f, _X); serialNodeLeaf(f, _Y); - f.serialCheck((uint32) 'END_'); + f.serialCheck(NELID("END_")); } diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp index ae06d0997..293582f52 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp @@ -591,7 +591,7 @@ bool CDBCtrlSheet::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup) return false; prop = (char*) xmlGetProp( cur, (xmlChar*)"dragable" ); - if( prop != NULL ) + if (prop) setDraggable( CInterfaceElement::convertBool(prop) ); else setDraggable( false ); diff --git a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet.cpp b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet.cpp index 5db9ce827..b5092be67 100644 --- a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet.cpp +++ b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet.cpp @@ -110,7 +110,7 @@ bool CDBGroupListSheet::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup) // value prop = xmlGetProp (cur, (xmlChar*)"value"); - if ( prop ) + if (prop) { // get a branch in the database. CCDBNodeBranch *branch= NLGUI::CDBManager::getInstance()->getDbBranch(prop); diff --git a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp index 6007c33b8..9d108926c 100644 --- a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp +++ b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_text.cpp @@ -94,7 +94,7 @@ bool CDBGroupListSheetText::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup) // value prop = xmlGetProp (cur, (xmlChar*)"value"); - if ( prop ) + if (prop) { // get a branch in the database. CCDBNodeBranch *branch= NLGUI::CDBManager::getInstance()->getDbBranch(prop); diff --git a/code/ryzom/client/src/interface_v3/filtered_chat_summary.cpp b/code/ryzom/client/src/interface_v3/filtered_chat_summary.cpp index 40b8c7bd4..d4a00e8e4 100644 --- a/code/ryzom/client/src/interface_v3/filtered_chat_summary.cpp +++ b/code/ryzom/client/src/interface_v3/filtered_chat_summary.cpp @@ -23,7 +23,7 @@ void CFilteredChatSummary::serial(NLMISC::IStream &f) throw(NLMISC::EStream) { sint ver= f.serialVersion(2); - f.serialCheck((uint32) 'USHC'); + f.serialCheck(NELID("USHC")); f.serial(SrcGuild); f.serial(SrcTeam); f.serial(SrcAroundMe); @@ -42,7 +42,7 @@ void CFilteredChatSummary::serial(NLMISC::IStream &f) throw(NLMISC::EStream) void CFilteredDynChatSummary::serial(NLMISC::IStream &f) throw(NLMISC::EStream) { sint ver = f.serialVersion(0); - f.serialCheck((uint32) 'USHC'); + f.serialCheck(NELID("USHC")); if (ver >= 0) { for (uint8 i = 0; i < CChatGroup::MaxDynChanPerPlayer; i++) diff --git a/code/ryzom/client/src/interface_v3/group_compas.cpp b/code/ryzom/client/src/interface_v3/group_compas.cpp index 20257cbaa..d4d0631ce 100644 --- a/code/ryzom/client/src/interface_v3/group_compas.cpp +++ b/code/ryzom/client/src/interface_v3/group_compas.cpp @@ -68,7 +68,7 @@ void CCompassTarget::serial(NLMISC::IStream &f) return; } } - f.serialCheck((uint32) 'CTAR'); + f.serialCheck(NELID("CTAR")); f.serialVersion(0); f.serial(Pos); // for the name, try to save a string identifier if possible, because language may be changed between @@ -95,7 +95,7 @@ void CCompassTarget::serial(NLMISC::IStream &f) _PositionState = NULL; } } - f.serialCheck((uint32) '_END'); + f.serialCheck(NELID("_END")); // if language has been modified, then we are not able to display correctly the name, so just // reset the compass to north to avoid incoherency if (f.isReading()) @@ -811,18 +811,19 @@ void CGroupCompasMenu::setActive (bool state) uint nbUserLandMarks = std::min( uint(currCont->UserLandMarks.size()), CContinent::getMaxNbUserLandMarks() ); // Sort the landmarks - std::sort(currCont->UserLandMarks.begin(), currCont->UserLandMarks.end(), UserLandMarksSortPredicate); + std::vector sortedLandmarks(currCont->UserLandMarks); + std::sort(sortedLandmarks.begin(), sortedLandmarks.end(), UserLandMarksSortPredicate); for(k = 0; k < nbUserLandMarks; ++k) { - if (currCont->UserLandMarks[k].Type < CUserLandMark::UserLandMarkTypeCount) + if (sortedLandmarks[k].Type < CUserLandMark::UserLandMarkTypeCount) { CCompassTarget ct; ct.setType(CCompassTarget::UserLandMark); - ct.Pos = currCont->UserLandMarks[k].Pos; - ct.Name = currCont->UserLandMarks[k].Title; + ct.Pos = sortedLandmarks[k].Pos; + ct.Name = sortedLandmarks[k].Title; Targets.push_back(ct); - landMarkSubMenus[currCont->UserLandMarks[k].Type]->addLine(ct.Name, "set_compas", toString("compass=%s|id=%d|menu=%s", _TargetCompass.c_str(), (int) Targets.size() - 1, _Id.c_str())); + landMarkSubMenus[sortedLandmarks[k].Type]->addLine(ct.Name, "set_compas", toString("compass=%s|id=%d|menu=%s", _TargetCompass.c_str(), (int) Targets.size() - 1, _Id.c_str())); selectable= true; } } diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index 9d1cb364a..9db2282fc 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -1663,7 +1663,7 @@ bool CInterfaceManager::loadConfig (const string &filename) // serial user chats info (serial it before position of windows so that they can be updated properly) if (ver >= 1) { - f.serialCheck(uint32('_ICU')); + f.serialCheck(NELID("_ICU")); if (!PeopleInterraction.loadUserChatsInfos(f)) { nlwarning("Bad user chat saving"); @@ -1671,7 +1671,7 @@ bool CInterfaceManager::loadConfig (const string &filename) } // header - f.serialCheck(uint32('GFCI')); + f.serialCheck(NELID("GFCI")); f.serial(nNbMode); f.serial(_CurrentMode); if(ver>=10) @@ -1897,7 +1897,7 @@ bool CInterfaceManager::saveConfig (const string &filename) f.serialVersion(ICFG_STREAM_VERSION); // serial user chats info (serial it before position of windows so that they can be updated properly) - f.serialCheck(uint32('_ICU')); + f.serialCheck(NELID("_ICU")); if (!PeopleInterraction.saveUserChatsInfos(f)) { nlwarning("Config saving failed"); @@ -1907,7 +1907,7 @@ bool CInterfaceManager::saveConfig (const string &filename) } // header - f.serialCheck(uint32('GFCI')); + f.serialCheck(NELID("GFCI")); f.serial(i); f.serial(_CurrentMode); f.serial(_LastInGameScreenW); diff --git a/code/ryzom/client/src/interface_v3/people_interraction.cpp b/code/ryzom/client/src/interface_v3/people_interraction.cpp index 95b091c22..332bcac57 100644 --- a/code/ryzom/client/src/interface_v3/people_interraction.cpp +++ b/code/ryzom/client/src/interface_v3/people_interraction.cpp @@ -1695,14 +1695,14 @@ bool CPeopleInterraction::saveUserChatsInfos(NLMISC::IStream &f) try { sint ver= f.serialVersion(USER_CHATS_INFO_VERSION); - f.serialCheck((uint32) 'TAHC'); + f.serialCheck(NELID("TAHC")); //saveFilteredChat(f, MainChat); saveFilteredChat(f, ChatGroup); for(uint k = 0; k < MaxNumUserChats; ++k) { saveFilteredChat(f, UserChat[k]); } - f.serialCheck((uint32) 'TAHC'); + f.serialCheck(NELID("TAHC")); if (ver>=1) { CChatGroupWindow *pCGW = PeopleInterraction.getChatGroupWindow(); @@ -1732,7 +1732,7 @@ bool CPeopleInterraction::saveUserDynChatsInfos(NLMISC::IStream &f) try { sint ver = f.serialVersion(USER_DYN_CHATS_INFO_VERSION); - f.serialCheck((uint32) 'OMGY'); + f.serialCheck(NELID("OMGY")); if (ver >= 1) { saveFilteredDynChat(f, TheUserChat); @@ -1755,7 +1755,7 @@ bool CPeopleInterraction::loadUserChatsInfos(NLMISC::IStream &f) { bool present; sint ver = f.serialVersion(USER_CHATS_INFO_VERSION); - f.serialCheck((uint32) 'TAHC'); + f.serialCheck(NELID("TAHC")); f.serial(present); if (!present) { @@ -1777,7 +1777,7 @@ bool CPeopleInterraction::loadUserChatsInfos(NLMISC::IStream &f) setupUserChatFromSummary(fcs, UserChat[k]); } } - f.serialCheck((uint32) 'TAHC'); + f.serialCheck(NELID("TAHC")); if (ver>=1) { // CChatGroupWindow *pCGW = PeopleInterraction.getChatGroupWindow(); @@ -1819,7 +1819,7 @@ bool CPeopleInterraction::loadUserDynChatsInfos(NLMISC::IStream &f) { bool present; sint ver = f.serialVersion(USER_DYN_CHATS_INFO_VERSION); - f.serialCheck((uint32) 'OMGY'); + f.serialCheck(NELID("OMGY")); f.serial(present); if (!present) { diff --git a/code/ryzom/client/src/landscape_poly_drawer.h b/code/ryzom/client/src/landscape_poly_drawer.h index 0012b5dcb..73d7fcadc 100644 --- a/code/ryzom/client/src/landscape_poly_drawer.h +++ b/code/ryzom/client/src/landscape_poly_drawer.h @@ -95,11 +95,11 @@ public: private: - // renderAll is called in main loop. It can called beginRenderLandscapePolyPart and renderLandscapePolyPart + // renderScene is called in main loop. It can called beginRenderLandscapePolyPart and renderLandscapePolyPart // methods. - friend void renderAll(bool); + friend void renderScene(); - // Enable stencil test and initialize function and operation of stencil at the beginning of renderAll method, + // Enable stencil test and initialize function and operation of stencil at the beginning of renderScene method, // before opaque render of canopy and main scene parts. // The eighth bit will be written with a 0 during next render to mark stencil buffer parts which will // support Shadow Volume algorithm. diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index 69fc35230..45e3fea51 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -1943,16 +1943,21 @@ class CAHInitResLod : public IActionHandler VideoModes.clear(); StringModeList.clear(); - StringModeList.push_back("uiConfigWindowed"); CurrentMode = getRyzomModes(VideoModes, StringModeList); + // getRyzomModes() expects empty list, so we need to insert 'Windowed' after mode list is filled + StringModeList.insert(StringModeList.begin(), "uiConfigWindowed"); + // If the client is in windowed mode, still in windowed mode and do not change anything if (ClientCfg.Windowed) CurrentMode = 0; // If we have not found the mode so it can be an error or machine change, so propose the first available else if (CurrentMode == -1) CurrentMode = 1; + // We inserted 'Windowed' as first mode, so index needs to move too + else + ++CurrentMode; CInterfaceManager *pIM = CInterfaceManager::getInstance(); CViewText *pVT = dynamic_cast(CWidgetManager::getInstance()->getElementFromId("ui:login:checkpass:content:res_value")); @@ -2111,7 +2116,12 @@ class CAHUninitResLod : public IActionHandler //nlinfo("CAHUninitResLod called"); // If the mode requested is a windowed mode do nothnig - if (CurrentMode != 0) + if (CurrentMode == 0) + { + ClientCfg.Windowed = true; + ClientCfg.writeBool("FullScreen", false); + } + else { ClientCfg.Windowed = false; // Get W, H @@ -2125,6 +2135,10 @@ class CAHUninitResLod : public IActionHandler } ClientCfg.Width = w; ClientCfg.Height = h; + + ClientCfg.writeBool("FullScreen", true); + ClientCfg.writeInt("Width", w); + ClientCfg.writeInt("Height", h); } if (CurrentPreset != 4) // CInterfaceDDX::CustomPreset diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 59519fc69..01336402d 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -42,6 +42,7 @@ #include "nel/3d/u_material.h" #include "nel/3d/u_instance_material.h" #include "nel/3d/u_cloud_scape.h" +#include "nel/3d/stereo_hmd.h" // game share #include "game_share/brick_types.h" #include "game_share/light_cycle.h" @@ -77,7 +78,7 @@ #include "world_database_manager.h" #include "continent_manager.h" #include "ig_callback.h" -#include "fog_map.h" +//#include "fog_map.h" #include "movie_shooter.h" #include "sound_manager.h" #include "graph.h" @@ -124,16 +125,6 @@ #include "nel/misc/check_fpu.h" -// TMP TMP -#include "nel/gui/ctrl_polygon.h" -// TMP TMP -#include "game_share/scenario_entry_points.h" -#include "nel/3d/driver.h" -#include "nel/3d/texture_file.h" - -#include "nel/3d/packed_world.h" -#include "nel/3d/packed_zone.h" -#include "nel/3d/driver_user.h" #ifdef USE_WATER_ENV_MAP @@ -148,6 +139,14 @@ #include "nel/gui/lua_manager.h" #include "nel/gui/group_table.h" +// pulled from main_loop.cpp +#include "ping.h" +#include "profiling.h" +#include "camera.h" +#include "main_loop_debug.h" +#include "main_loop_temp.h" +#include "main_loop_utilities.h" + /////////// // USING // @@ -159,20 +158,12 @@ using namespace NLNET; using namespace std; -// TMP TMP -static void viewportToScissor(const CViewport &vp, CScissor &scissor) -{ - scissor.X = vp.getX(); - scissor.Y = vp.getY(); - scissor.Width = vp.getWidth(); - scissor.Height = vp.getHeight(); -} + //////////// // EXTERN // //////////// -extern std::set LodCharactersNotFound; extern UDriver *Driver; extern IMouseDevice *MouseDevice; extern UScene *Scene; @@ -187,13 +178,16 @@ extern TTime UniversalTime; extern UMaterial GenericMat; extern UCamera MainCam; extern CEventsListener EventsListener; -extern uint32 NbDatabaseChanges; extern CMatrix MainSceneViewMatrix; extern CMatrix InvMainSceneViewMatrix; extern std::vector LogoBitmaps; extern bool IsInRingSession; extern std::string UsedFSAddr; +// temp +extern NLMISC::CValueSmoother smoothFPS; +extern NLMISC::CValueSmoother moreSmoothFPS; + void loadBackgroundBitmap (TBackground background); void destroyLoadingBitmap (); void drawLoadingBitmap (float progress); @@ -216,84 +210,6 @@ uint64 SimulatedServerTick = 0; -/////////// -// CLASS // -/////////// -/** - * Class to manage the ping computed with the database. - * \author Guillaume PUZIN - * \author Nevrax France - * \date 2003 - */ -class CPing : public ICDBNode::IPropertyObserver -{ -private: - uint32 _Ping; - bool _RdyToPing; - -public: - // Constructor. - CPing() {_Ping = 0; _RdyToPing = true;} - // Destructor. - ~CPing() {;} - - // Add an observer on the database for the ping. - void init() - { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - if(pIM) - { - CCDBNodeLeaf *pNodeLeaf = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:DEBUG_INFO:Ping", false); - if(pNodeLeaf) - { - ICDBNode::CTextId textId; - pNodeLeaf->addObserver(this, textId); - // nlwarning("CPing: cannot add the observer"); - } - else - nlwarning("CPing: 'SERVER:DEBUG_INFO:Ping' does not exist."); - } - } - - // Release the observer on the database for the ping. - void release() - { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - if(pIM) - { - CCDBNodeLeaf *pNodeLeaf = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:DEBUG_INFO:Ping", false); - if(pNodeLeaf) - { - ICDBNode::CTextId textId; - pNodeLeaf->removeObserver(this, textId); - } - else - nlwarning("CPing: 'SERVER:DEBUG_INFO:Ping' does not exist."); - } - } - - // Method called when the ping message is back. - virtual void update(ICDBNode* node) - { - CCDBNodeLeaf *leaf = safe_cast(node); - uint32 before = (uint32)leaf->getValue32(); - uint32 current = (uint32)(0xFFFFFFFF & ryzomGetLocalTime()); - if(before > current) - { - //nlwarning("DB PING Pb before '%u' after '%u'.", before, current); - if(ClientCfg.Check) - nlstop; - } - _Ping = current - before; - _RdyToPing = true; - } - - // return the ping in ms. - uint32 getValue() {return _Ping;} - - void rdyToPing(bool rdy) {_RdyToPing = rdy;} - bool rdyToPing() const {return _RdyToPing;} -}; ///////////// // GLOBALS // @@ -327,12 +243,6 @@ uint8 ShowInfos = 0; // 0=no info 1=text info 2=graph info bool bZeroCpu = false; // For no Cpu use if application is minimize TODO: intercept minimize message, called by CTRL + Z at this -bool Profiling = false; // Are we in Profile mode? -uint ProfileNumFrame = 0; -bool WantProfiling = false; -bool ProfilingVBLock = false; -bool WantProfilingVBLock = false; - bool MovieShooterSaving= false; // Are we in Shooting mode? @@ -379,8 +289,6 @@ CGameContextMenu GameContextMenu; -NLMISC::CValueSmoother smoothFPS; -NLMISC::CValueSmoother moreSmoothFPS(64); static CRefPtr s_FpsLeaf; static CRefPtr s_UiDirectionLeaf; @@ -425,12 +333,6 @@ H_AUTO_DECL ( RZ_Client_Main_Loop_Net ) /////////////// // FUNCTIONS // /////////////// -// Display some debug infos. -void displayDebug(); -void displayDebugFps(); -void displayDebugUIUnderMouse(); -// Display an Help. -void displayHelp(); //update the sound manager (listener pos, user walk/run sound...) void updateSound(); @@ -453,476 +355,11 @@ void displaySceneProfiles(); // validate current dialogs (end them if the player is too far from its interlocutor) void validateDialogs(const CGameContextMenu &gcm); -void buildCameraClippingPyramid (vector &planes) -{ - // Compute pyramid in view basis. - CVector pfoc(0,0,0); - const CFrustum &frustum = MainCam.getFrustum(); - InvMainSceneViewMatrix = MainCam.getMatrix(); - MainSceneViewMatrix = InvMainSceneViewMatrix; - MainSceneViewMatrix.invert(); - - CVector lb(frustum.Left, frustum.Near, frustum.Bottom ); - CVector lt(frustum.Left, frustum.Near, frustum.Top ); - CVector rb(frustum.Right, frustum.Near, frustum.Bottom ); - CVector rt(frustum.Right, frustum.Near, frustum.Top ); - - CVector lbFar(frustum.Left, ClientCfg.CharacterFarClip, frustum.Bottom); - CVector ltFar(frustum.Left, ClientCfg.CharacterFarClip, frustum.Top ); - CVector rtFar(frustum.Right, ClientCfg.CharacterFarClip, frustum.Top ); - - planes.resize (4); - // planes[0].make(lbFar, ltFar, rtFar); - planes[0].make(pfoc, lt, lb); - planes[1].make(pfoc, rt, lt); - planes[2].make(pfoc, rb, rt); - planes[3].make(pfoc, lb, rb); - - // Compute pyramid in World basis. - // The vector transformation M of a plane p is computed as p*M-1. - // Here, ViewMatrix== CamMatrix-1. Hence the following formula. - uint i; - - for (i = 0; i < 4; i++) - { - planes[i] = planes[i]*MainSceneViewMatrix; - } -} - - -//--------------------------------------------------- -// Test Profiling and run? -//--------------------------------------------------- -void testLaunchProfile() -{ - if(!WantProfiling) - return; - - // comes from ActionHandler - WantProfiling= false; - -#ifdef _PROFILE_ON_ - if( !Profiling ) - { - // start the bench. - NLMISC::CHTimer::startBench(); - ProfileNumFrame = 0; - Driver->startBench(); - if (SoundMngr) - SoundMngr->getMixer()->startDriverBench(); - // state - Profiling= true; - } - else - { - // end the bench. - if (SoundMngr) - SoundMngr->getMixer()->endDriverBench(); - NLMISC::CHTimer::endBench(); - Driver->endBench(); - - - // Display and save profile to a File. - CLog log; - CFileDisplayer fileDisplayer(NLMISC::CFile::findNewFile(getLogDirectory() + "profile.log")); - CStdDisplayer stdDisplayer; - log.addDisplayer(&fileDisplayer); - log.addDisplayer(&stdDisplayer); - // diplay - NLMISC::CHTimer::displayHierarchicalByExecutionPathSorted(&log, CHTimer::TotalTime, true, 48, 2); - NLMISC::CHTimer::displayHierarchical(&log, true, 48, 2); - NLMISC::CHTimer::displayByExecutionPath(&log, CHTimer::TotalTime); - NLMISC::CHTimer::display(&log, CHTimer::TotalTime); - NLMISC::CHTimer::display(&log, CHTimer::TotalTimeWithoutSons); - Driver->displayBench(&log); - - if (SoundMngr) - SoundMngr->getMixer()->displayDriverBench(&log); - - // state - Profiling= false; - } -#endif // #ifdef _PROFILE_ON_ -} - - -//--------------------------------------------------- -// Test ProfilingVBLock and run? -//--------------------------------------------------- -void testLaunchProfileVBLock() -{ - // If running, must stop for this frame. - if(ProfilingVBLock) - { - vector strs; - Driver->endProfileVBHardLock(strs); - nlinfo("Profile VBLock"); - nlinfo("**************"); - for(uint i=0;iprofileVBHardAllocation(strs); - for(uint i=0;iendProfileIBLock(strs); - nlinfo("Profile Index Buffer Lock"); - nlinfo("**************"); - for(uint i=0;iprofileIBAllocation(strs); - for(uint i=0;istartProfileVBHardLock(); - Driver->startProfileIBLock(); - } -} - - -//--------------------------------------------------- -// update the camera perspective setup -//--------------------------------------------------- -void updateCameraPerspective() -{ - float fov, aspectRatio; - computeCurrentFovAspectRatio(fov, aspectRatio); - - // change the perspective of the scene - if(!MainCam.empty()) - MainCam.setPerspective(fov, aspectRatio, CameraSetupZNear, ClientCfg.Vision); - // change the perspective of the root scene - if(SceneRoot) - { - UCamera cam= SceneRoot->getCam(); - cam.setPerspective(fov, aspectRatio, SceneRootCameraZNear, SceneRootCameraZFar); - } -} - -//--------------------------------------------------- -// Compare ClientCfg and LastClientCfg to know what we must update -//--------------------------------------------------- -void updateFromClientCfg() -{ - CClientConfig::setValues(); - ClientCfg.IsInvalidated = false; - - // GRAPHICS - GENERAL - //--------------------------------------------------- - if ((ClientCfg.Windowed != LastClientCfg.Windowed) || - (ClientCfg.Width != LastClientCfg.Width) || - (ClientCfg.Height != LastClientCfg.Height) || - (ClientCfg.Depth != LastClientCfg.Depth) || - (ClientCfg.Frequency != LastClientCfg.Frequency)) - { - setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, - ClientCfg.Windowed, ClientCfg.Frequency)); - } - - if (ClientCfg.DivideTextureSizeBy2 != LastClientCfg.DivideTextureSizeBy2) - { - if (ClientCfg.DivideTextureSizeBy2) - Driver->forceTextureResize(2); - else - Driver->forceTextureResize(1); - } - - //--------------------------------------------------- - if (ClientCfg.WaitVBL != LastClientCfg.WaitVBL) - { - if(ClientCfg.WaitVBL) - Driver->setSwapVBLInterval(1); - else - Driver->setSwapVBLInterval(0); - } - - // GRAPHICS - LANDSCAPE - //--------------------------------------------------- - if (ClientCfg.LandscapeThreshold != LastClientCfg.LandscapeThreshold) - { - if (Landscape) Landscape->setThreshold(ClientCfg.getActualLandscapeThreshold()); - } - - //--------------------------------------------------- - if (ClientCfg.LandscapeTileNear != LastClientCfg.LandscapeTileNear) - { - if (Landscape) Landscape->setTileNear(ClientCfg.LandscapeTileNear); - } - - //--------------------------------------------------- - if (Landscape) - { - if (ClientCfg.Vision != LastClientCfg.Vision) - { - if (!ClientCfg.Light) - { - // Not in an indoor ? - if (ContinentMngr.cur() && !ContinentMngr.cur()->Indoor) - { - // Refresh All Zone in streaming according to the refine position - vector zonesAdded; - vector zonesRemoved; - const R2::CScenarioEntryPoints::CCompleteIsland *ci = R2::CScenarioEntryPoints::getInstance().getCompleteIslandFromCoords(CVector2f((float) UserEntity->pos().x, (float) UserEntity->pos().y)); - Landscape->refreshAllZonesAround(View.refinePos(), ClientCfg.Vision + ExtraZoneLoadingVision, zonesAdded, zonesRemoved, ProgressBar, ci ? &(ci->ZoneIDs) : NULL); - LandscapeIGManager.unloadArrayZoneIG(zonesRemoved); - LandscapeIGManager.loadArrayZoneIG(zonesAdded); - } - } - } - } - - //--------------------------------------------------- - if (ClientCfg.Vision != LastClientCfg.Vision || ClientCfg.FoV!=LastClientCfg.FoV || - ClientCfg.Windowed != LastClientCfg.Windowed || ClientCfg.ScreenAspectRatio != LastClientCfg.ScreenAspectRatio ) - { - updateCameraPerspective(); - } - - //--------------------------------------------------- - if (Landscape) - { - if (ClientCfg.MicroVeget != LastClientCfg.MicroVeget) - { - if(ClientCfg.MicroVeget) - { - // if configured, enable the vegetable and load the texture. - Landscape->enableVegetable(true); - // Default setup. TODO later by gameDev. - Landscape->setVegetableWind(CVector(0.5, 0.5, 0).normed(), 0.5, 1, 0); - // Default setup. should work well for night/day transition in 30 minutes. - // Because all vegetables will be updated every 20 seconds => 90 steps. - Landscape->setVegetableUpdateLightingFrequency(1/20.f); - // Density (percentage to ratio) - Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f); - } - else - { - Landscape->enableVegetable(false); - } - } - } - - //--------------------------------------------------- - if (ClientCfg.MicroVegetDensity != LastClientCfg.MicroVegetDensity) - { - // Density (percentage to ratio) - if (Landscape) Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f); - } - - // GRAPHICS - SPECIAL EFFECTS - //--------------------------------------------------- - if (ClientCfg.FxNbMaxPoly != LastClientCfg.FxNbMaxPoly) - { - if (Scene->getGroupLoadMaxPolygon("Fx") != ClientCfg.FxNbMaxPoly) - Scene->setGroupLoadMaxPolygon("Fx", ClientCfg.FxNbMaxPoly); - } - - //--------------------------------------------------- - if (ClientCfg.Cloud != LastClientCfg.Cloud) - { - if (ClientCfg.Cloud) - { - InitCloudScape = true; - CloudScape = Scene->createCloudScape(); - } - else - { - if (CloudScape != NULL) - Scene->deleteCloudScape(CloudScape); - CloudScape = NULL; - } - } - - //--------------------------------------------------- - if (ClientCfg.CloudQuality != LastClientCfg.CloudQuality) - { - if (CloudScape != NULL) - CloudScape->setQuality(ClientCfg.CloudQuality); - } - - //--------------------------------------------------- - if (ClientCfg.CloudUpdate != LastClientCfg.CloudUpdate) - { - if (CloudScape != NULL) - CloudScape->setNbCloudToUpdateIn80ms(ClientCfg.CloudUpdate); - } - - //--------------------------------------------------- - if (ClientCfg.Shadows != LastClientCfg.Shadows) - { - // Enable/Disable Receive on Landscape - if(Landscape) - { - Landscape->enableReceiveShadowMap(ClientCfg.Shadows); - } - // Enable/Disable Cast for all entities - for(uint i=0;iupdateCastShadowMap(); - } - } - - // GRAPHICS - CHARACTERS - //--------------------------------------------------- - if (ClientCfg.SkinNbMaxPoly != LastClientCfg.SkinNbMaxPoly) - { - if (Scene->getGroupLoadMaxPolygon("Skin") != ClientCfg.SkinNbMaxPoly) - Scene->setGroupLoadMaxPolygon("Skin", ClientCfg.SkinNbMaxPoly); - } - - //--------------------------------------------------- - if (ClientCfg.NbMaxSkeletonNotCLod != LastClientCfg.NbMaxSkeletonNotCLod ) - { - Scene->setMaxSkeletonsInNotCLodForm(ClientCfg.NbMaxSkeletonNotCLod); - } - - //--------------------------------------------------- - if (ClientCfg.CharacterFarClip != LastClientCfg.CharacterFarClip) - { - // Nothing to do - } - - //--------------------------------------------------- - if (ClientCfg.HDEntityTexture != LastClientCfg.HDEntityTexture) - { - // Don't reload Texture, will be done at next Game Start - } - - // INTERFACE works - - - // INPUTS - //--------------------------------------------------- - if (ClientCfg.CursorSpeed != LastClientCfg.CursorSpeed) - SetMouseSpeed (ClientCfg.CursorSpeed); - - if (ClientCfg.CursorAcceleration != LastClientCfg.CursorAcceleration) - SetMouseAcceleration (ClientCfg.CursorAcceleration); - - if (ClientCfg.HardwareCursor != LastClientCfg.HardwareCursor) - { - if (ClientCfg.HardwareCursor != IsMouseCursorHardware()) - { - InitMouseWithCursor (ClientCfg.HardwareCursor); - } - } - - - // SOUND - //--------------------------------------------------- - bool mustReloadSoundMngrContinent= false; - - // disable/enable sound? - if (ClientCfg.SoundOn != LastClientCfg.SoundOn) - { - if (SoundMngr && !ClientCfg.SoundOn) - { - nlwarning("Deleting sound manager..."); - delete SoundMngr; - SoundMngr = NULL; - } - else if (SoundMngr == NULL && ClientCfg.SoundOn) - { - nlwarning("Creating sound manager..."); - SoundMngr = new CSoundManager(); - try - { - SoundMngr->init(NULL); - } - catch(const Exception &e) - { - nlwarning("init : Error when creating 'SoundMngr' : %s", e.what()); - SoundMngr = 0; - } - - // re-init with good SFX/Music Volume - if(SoundMngr) - { - SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume); - SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume); - } - } - else - { - nlwarning("Sound config error !"); - } - - mustReloadSoundMngrContinent= true; - } - // change EAX? - if ( SoundMngr && LastClientCfg.SoundOn && - (ClientCfg.UseEax != LastClientCfg.UseEax) ) - { - SoundMngr->reset(); - - mustReloadSoundMngrContinent= true; - } - - // change SoundForceSoftwareBuffer? - if ( SoundMngr && LastClientCfg.SoundOn && - (ClientCfg.SoundForceSoftwareBuffer != LastClientCfg.SoundForceSoftwareBuffer) ) - { - SoundMngr->reset(); - - mustReloadSoundMngrContinent= true; - } - - // change MaxTrack? don't reset - if ( SoundMngr && LastClientCfg.SoundOn && - (ClientCfg.MaxTrack != LastClientCfg.MaxTrack)) - { - SoundMngr->getMixer()->changeMaxTrack(ClientCfg.MaxTrack); - } - - // change SoundFX Volume? don't reset - if (SoundMngr && ClientCfg.SoundSFXVolume != LastClientCfg.SoundSFXVolume) - { - SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume); - } - - // change Game Music Volume? don't reset - if (SoundMngr && ClientCfg.SoundGameMusicVolume != LastClientCfg.SoundGameMusicVolume) - { - SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume); - } - - // reload only if active and reseted - if (mustReloadSoundMngrContinent && SoundMngr && ContinentMngr.cur() && !ContinentMngr.cur()->Indoor && UserEntity) - { - SoundMngr->loadContinent(ContinentMngr.getCurrentContinentSelectName(), UserEntity->pos()); - } +// *************************************************************************** - // Ok backup the new clientcfg - LastClientCfg = ClientCfg; -} +enum TSkyMode { NoSky, OldSky, NewSky }; +static TSkyMode s_SkyMode = NoSky; void preRenderNewSky () { @@ -934,29 +371,43 @@ void preRenderNewSky () cd.Hour = 12.f; } sky.setup(cd, SmoothedClientDate, WeatherManager.getWeatherValue(), MainFogState.FogColor, Scene->getSunDirection(), false); - // setup camera - CFrustum frust = MainCam.getFrustum(); - UCamera camSky = sky.getScene()->getCam(); - sky.getScene()->setViewport(Scene->getViewport()); - camSky.setTransformMode(UTransform::DirectMatrix); - // must have our own Far!!! - frust.Far= SkyCameraZFar; - camSky.setFrustum(frust); - CMatrix skyCameraMatrix; - skyCameraMatrix.identity(); - skyCameraMatrix= MainCam.getMatrix(); - skyCameraMatrix.setPos(CVector::Null); - camSky.setMatrix(skyCameraMatrix); } -//uint32 MainLoopCounter = 0; +void commitCamera() +{ + // Set the sky camera + if (s_SkyMode == NewSky) + { + CSky &sky = ContinentMngr.cur()->CurrentSky; + // setup camera + CFrustum frust = MainCam.getFrustum(); + UCamera camSky = sky.getScene()->getCam(); + sky.getScene()->setViewport(Scene->getViewport()); + camSky.setTransformMode(UTransform::DirectMatrix); + // must have our own Far!!! + frust.Far= SkyCameraZFar; + camSky.setFrustum(frust); + CMatrix skyCameraMatrix; + skyCameraMatrix.identity(); + skyCameraMatrix= MainCam.getMatrix(); + skyCameraMatrix.setPos(CVector::Null); + camSky.setMatrix(skyCameraMatrix); + } + // Set The Root Camera + UCamera camRoot = SceneRoot->getCam(); + if(!camRoot.empty()) + { + // Update Camera Position/Rotation. + //camRoot.setPos(View.currentViewPos()); + //camRoot.setRotQuat(View.currentViewQuat()); + camRoot.setPos(MainCam.getPos()); + camRoot.setRotQuat(MainCam.getRotQuat()); + } +} // *************************************************************************** -enum TSkyMode { NoSky, OldSky, NewSky }; - -// *************************************************************************** void beginRenderCanopyPart() { SceneRoot->beginPartRender(); @@ -975,17 +426,17 @@ void endRenderMainScenePart() Scene->endPartRender(true); } -void beginRenderSkyPart(TSkyMode skyMode) +void beginRenderSkyPart() { - if(skyMode == NewSky) + if (s_SkyMode == NewSky) { CSky &sky = ContinentMngr.cur()->CurrentSky; sky.getScene()->beginPartRender(); } } -void endRenderSkyPart(TSkyMode skyMode) +void endRenderSkyPart() { - if(skyMode == NewSky) + if (s_SkyMode == NewSky) { CSky &sky = ContinentMngr.cur()->CurrentSky; sky.getScene()->endPartRender(false); @@ -1003,14 +454,6 @@ static void renderCanopyPart(UScene::TRenderPart renderPart) ContinentMngr.getFogState(CanopyFog, LightCycleManager.getLightLevel(), LightCycleManager.getLightDesc().DuskRatio, LightCycleManager.getState(), View.viewPos(), RootFogState); RootFogState.setupInDriver(*Driver); - // Set The Root Camera - UCamera camRoot = SceneRoot->getCam(); - if(!camRoot.empty()) - { - // Update Camera Position/Rotation. - camRoot.setPos(View.currentViewPos()); - camRoot.setRotQuat(View.currentView()); - } // Render the root scene SceneRoot->renderPart(renderPart); } @@ -1035,12 +478,12 @@ static void renderMainScenePart(UScene::TRenderPart renderPart) // *************************************************************************************************************************** // Render a part of the sky -static void renderSkyPart(UScene::TRenderPart renderPart, TSkyMode skyMode) +static void renderSkyPart(UScene::TRenderPart renderPart) { - nlassert(skyMode != NoSky); + nlassert(s_SkyMode != NoSky); Driver->setDepthRange(SKY_DEPTH_RANGE_START, 1.f); Driver->enableFog(false); - if (skyMode == NewSky) + if (s_SkyMode == NewSky) { CSky &sky = ContinentMngr.cur()->CurrentSky; sky.getScene()->renderPart(renderPart); @@ -1059,12 +502,67 @@ static void renderSkyPart(UScene::TRenderPart renderPart, TSkyMode skyMode) #endif } - // *************************************************************************************************************************** -// Render all scenes -void renderAll(bool forceFullDetail) +// Utility to force full detail +struct CForceFullDetail { - if (ClientCfg.Bloom) +public: + void backup() + { + maxFullDetailChar = Scene->getMaxSkeletonsInNotCLodForm(); + oldBalancingMode = Scene->getPolygonBalancingMode(); + oldSkyBalancingMode = UScene::PolygonBalancingOff; + UScene *skyScene = getSkyScene(); + if (skyScene) oldSkyBalancingMode = skyScene->getPolygonBalancingMode(); + } + void set() + { + Scene->setMaxSkeletonsInNotCLodForm(1000000); + Scene->setPolygonBalancingMode(UScene::PolygonBalancingOff); + UScene *skyScene = getSkyScene(); + if (skyScene) skyScene->setPolygonBalancingMode(UScene::PolygonBalancingOff); + } + void restore() + { + Scene->setMaxSkeletonsInNotCLodForm(maxFullDetailChar); + Scene->setPolygonBalancingMode(oldBalancingMode); + UScene *skyScene = getSkyScene(); + if (skyScene) skyScene->setPolygonBalancingMode(oldSkyBalancingMode); + } +private: + uint maxFullDetailChar; + UScene::TPolygonBalancingMode oldBalancingMode; + UScene::TPolygonBalancingMode oldSkyBalancingMode; +}; +static CForceFullDetail s_ForceFullDetail; + +void clearBuffers() +{ + if (Render) + { + if (Driver->getPolygonMode() == UDriver::Filled) + { + Driver->clearZBuffer(); + } + + // Sky is used to clear the frame buffer now, but if in line or point polygon mode, we should draw it + if (Driver->getPolygonMode() != UDriver::Filled) + { + if (!Driver->isLost()) + { + Driver->clearBuffers (CRGBA(127, 127, 127)); + } + } + } + else + { + Driver->clearBuffers(ClientCfg.BGColor); + } +} + +void renderScene(bool forceFullDetail, bool bloom) +{ + if (bloom) { // set bloom parameters before applying bloom effect CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); @@ -1072,105 +570,125 @@ void renderAll(bool forceFullDetail) // init bloom CBloomEffect::getInstance().initBloom(); } - - // backup old balancing mode - uint maxFullDetailChar = Scene->getMaxSkeletonsInNotCLodForm(); - UScene *skyScene = getSkyScene(); - UScene::TPolygonBalancingMode oldBalancingMode = Scene->getPolygonBalancingMode(); - UScene::TPolygonBalancingMode oldSkyBalancingMode = UScene::PolygonBalancingOff; - if (skyScene) + if (forceFullDetail) { - oldSkyBalancingMode = skyScene->getPolygonBalancingMode(); + s_ForceFullDetail.backup(); + s_ForceFullDetail.set(); } - // disable load balancing for that frame only if asked + clearBuffers(); + renderScene(); if (forceFullDetail) { - Scene->setMaxSkeletonsInNotCLodForm(1000000); - Scene->setPolygonBalancingMode(UScene::PolygonBalancingOff); - if (skyScene) - { - skyScene->setPolygonBalancingMode(UScene::PolygonBalancingOff); - } + s_ForceFullDetail.restore(); } - + if (bloom) { - H_AUTO_USE ( RZ_Client_Main_Loop_Sky_And_Weather ) + // apply bloom effect + CBloomEffect::getInstance().endBloom(); + CBloomEffect::getInstance().endInterfacesDisplayBloom(); + } +} - //HeightGrid.update(Scene->getCam().getPos()); +// *************************************************************************************************************************** - // update description of light cycle - updateLightDesc(); +void updateWaterEnvMap() +{ + #ifdef USE_WATER_ENV_MAP + if (WaterEnvMapRefCount > 0) // water env map needed + { + if (!WaterEnvMap) + { + CSky &sky = ContinentMngr.cur()->CurrentSky; + if (sky.getScene()) + { + nlassert(WaterEnvMapSkyCam.empty()); + WaterEnvMapSkyCam = sky.getScene()->createCamera(); // deleted in unselect + nlassert(WaterEnvMapCanopyCam.empty()); + WaterEnvMapCanopyCam = SceneRoot->createCamera(); // deleted in unselect + // Create water env map if not already created + WaterEnvMap = Driver->createWaterEnvMap(); + if(WaterEnvMap) + { + WaterEnvMap->init(128, 256, ClientCfg.WaterEnvMapUpdateTime); + WaterEnvMap->setWaterEnvMapRenderCallback(&WaterEnvMapRdr); + Scene->setWaterEnvMap(WaterEnvMap); + } + } + } + WaterEnvMapRdr.CurrDate = SmoothedClientDate; + WaterEnvMapRdr.AnimationDate = SmoothedClientDate; + if (ClientCfg.R2EDEnabled && R2::getEditor().getFixedLighting()) + { + WaterEnvMapRdr.CurrDate.Hour = 12.f; + } + WaterEnvMapRdr.CurrFogColor = MainFogState.FogColor; + WaterEnvMapRdr.CurrTime = TimeInSec - FirstTimeInSec; + WaterEnvMapRdr.CurrWeather = WeatherManager.getWeatherValue(); + CSky &sky = ContinentMngr.cur()->CurrentSky; + WaterEnvMap->setAlpha(sky.getWaterEnvMapAlpha()); + Scene->updateWaterEnvMaps(TimeInSec - FirstTimeInSec); + } + #endif +} - // server driven weather mgt - updateDBDrivenWeatherValue(); +// *************************************************************************************************************************** - // Update the weather manager - updateWeatherManager(MainCam.getMatrix(), ContinentMngr.cur()); +void updateWeather() +{ + H_AUTO_USE ( RZ_Client_Main_Loop_Sky_And_Weather ) - // compute thunder color - ThunderColor.modulateFromui(WeatherManager.getCurrWeatherState().ThunderColor, (uint) (256.f * WeatherManager.getThunderLevel())); + //HeightGrid.update(Scene->getCam().getPos()); - // Update the lighting - LightCycleManager.setHour(DayNightCycleHour, WeatherManager, ThunderColor); + // update description of light cycle + updateLightDesc(); - #ifdef RENDER_CLOUDS - if (Filter3D[FilterCloud]) - { - H_AUTO_USE ( RZ_Client_Main_Loop_Update_Cloud_Scape ); - updateClouds(); - } - #endif + // server driven weather mgt + updateDBDrivenWeatherValue(); + // Update the weather manager + updateWeatherManager(MainCam.getMatrix(), ContinentMngr.cur()); - ContinentMngr.getFogState(MainFog, LightCycleManager.getLightLevel(), LightCycleManager.getLightDesc().DuskRatio, LightCycleManager.getState(), View.viewPos(), MainFogState); + // compute thunder color + ThunderColor.modulateFromui(WeatherManager.getCurrWeatherState().ThunderColor, (uint) (256.f * WeatherManager.getThunderLevel())); - if (Driver->getPolygonMode() == UDriver::Filled) - { - Driver->clearZBuffer(); - } + // Update the lighting + LightCycleManager.setHour(DayNightCycleHour, WeatherManager, ThunderColor); - #ifdef RENDER_CLOUDS - if (CloudScape != NULL && Filter3D[FilterCloud]) - { - H_AUTO_USE ( RZ_Client_Main_Loop_Anim_Cloud_Scape ); + #ifdef RENDER_CLOUDS + if (Filter3D[FilterCloud]) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Update_Cloud_Scape ); + updateClouds(); + } + #endif + + ContinentMngr.getFogState(MainFog, LightCycleManager.getLightLevel(), LightCycleManager.getLightDesc().DuskRatio, LightCycleManager.getState(), View.viewPos(), MainFogState); - Driver->enableFog (false); + // TODO: ZBuffer clear was originally before this, but should not be necessary normally. + // The anim function renders new clouds. Ensure this does not break. + // These are old-style nel clouds. - // Force polygon mode to filled - NL3D::UDriver::TPolygonMode oldMode = Driver->getPolygonMode(); - Driver->setPolygonMode(NL3D::UDriver::Filled); + #ifdef RENDER_CLOUDS + if (CloudScape != NULL && Filter3D[FilterCloud]) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Anim_Cloud_Scape ); - CloudScape->anim (DT); // WARNING this function work with screen + Driver->enableFog (false); - Driver->enableFog (true); + // Force polygon mode to filled + NL3D::UDriver::TPolygonMode oldMode = Driver->getPolygonMode(); + Driver->setPolygonMode(NL3D::UDriver::Filled); - // Reset backuped polygon mode - Driver->setPolygonMode(oldMode); - } - #endif - // Sky is used to clear the frame buffer now, but if in line or point polygon mode, we should draw it - if (Driver->getPolygonMode() != UDriver::Filled) - { - if (!Driver->isLost()) - { - Driver->clearBuffers (CRGBA(127, 127, 127)); - } - } - } - // Update Filter Flags - Scene->enableElementRender(UScene::FilterAllMeshNoVP, Filter3D[FilterMeshNoVP]); - Scene->enableElementRender(UScene::FilterAllMeshVP, Filter3D[FilterMeshVP]); - Scene->enableElementRender(UScene::FilterFX, Filter3D[FilterFXs]); - Scene->enableElementRender(UScene::FilterLandscape, Filter3D[FilterLandscape]); - Scene->enableElementRender(UScene::FilterSkeleton, Filter3D[FilterSkeleton]); - Scene->enableElementRender(UScene::FilterWater, Filter3D[FilterWater]); - Scene->enableElementRender(UScene::FilterCoarseMesh, Filter3D[FilterCoarseMesh]); + CloudScape->anim (DT); // WARNING this function work with screen - // profile this frame? - if(Scene_Profile) - Scene->profileNextRender(); + Driver->enableFog (true); - TSkyMode skyMode = NoSky; + // Reset backuped polygon mode + Driver->setPolygonMode(oldMode); + } + #endif + + // Update new sky if (ContinentMngr.cur() && !ContinentMngr.cur()->Indoor) { if(Driver->getPolygonMode() == UDriver::Filled) @@ -1180,18 +698,36 @@ void renderAll(bool forceFullDetail) CSky &sky = ContinentMngr.cur()->CurrentSky; if (sky.getScene()) { - skyMode = NewSky; + s_SkyMode = NewSky; sky.getScene()->animate(TimeInSec-FirstTimeInSec); // Setup the sky camera preRenderNewSky(); } else { - skyMode = OldSky; + s_SkyMode = OldSky; } } } } +} + +// *************************************************************************************************************************** +// Render all scenes +void renderScene() +{ + // Update Filter Flags + Scene->enableElementRender(UScene::FilterAllMeshNoVP, Filter3D[FilterMeshNoVP]); + Scene->enableElementRender(UScene::FilterAllMeshVP, Filter3D[FilterMeshVP]); + Scene->enableElementRender(UScene::FilterFX, Filter3D[FilterFXs]); + Scene->enableElementRender(UScene::FilterLandscape, Filter3D[FilterLandscape]); + Scene->enableElementRender(UScene::FilterSkeleton, Filter3D[FilterSkeleton]); + Scene->enableElementRender(UScene::FilterWater, Filter3D[FilterWater]); + Scene->enableElementRender(UScene::FilterCoarseMesh, Filter3D[FilterCoarseMesh]); + + // profile this frame? + if(Scene_Profile) + Scene->profileNextRender(); // initialisation of polygons renderer CLandscapePolyDrawer::getInstance().beginRenderLandscapePolyPart(); @@ -1199,7 +735,7 @@ void renderAll(bool forceFullDetail) // Start Part Rendering beginRenderCanopyPart(); beginRenderMainScenePart(); - beginRenderSkyPart(skyMode); + beginRenderSkyPart(); // Render part // WARNING: always must begin rendering with at least UScene::RenderOpaque, // else dynamic shadows won't work @@ -1209,32 +745,17 @@ void renderAll(bool forceFullDetail) // render of polygons on landscape CLandscapePolyDrawer::getInstance().renderLandscapePolyPart(); - if (skyMode != NoSky) renderSkyPart((UScene::TRenderPart) (UScene::RenderOpaque | UScene::RenderTransparent), skyMode); + if (s_SkyMode != NoSky) renderSkyPart((UScene::TRenderPart) (UScene::RenderOpaque | UScene::RenderTransparent)); renderCanopyPart((UScene::TRenderPart) (UScene::RenderTransparent | UScene::RenderFlare)); renderMainScenePart((UScene::TRenderPart) (UScene::RenderTransparent | UScene::RenderFlare)); - if (skyMode == NewSky) renderSkyPart(UScene::RenderFlare, skyMode); + if (s_SkyMode == NewSky) renderSkyPart(UScene::RenderFlare); // End Part Rendering - endRenderSkyPart(skyMode); + endRenderSkyPart(); endRenderMainScenePart(); endRenderCanopyPart(); // reset depth range Driver->setDepthRange(0.f, CANOPY_DEPTH_RANGE_START); - - // restore load balancing mode - if (forceFullDetail) - { - Scene->setMaxSkeletonsInNotCLodForm(maxFullDetailChar); - Scene->setPolygonBalancingMode(oldBalancingMode); - if (skyScene) - { - skyScene->setPolygonBalancingMode(oldSkyBalancingMode); - } - } - - // apply bloom effect - if (ClientCfg.Bloom) - CBloomEffect::getInstance().endBloom(); } @@ -1538,6 +1059,14 @@ bool mainLoop() while( !UserEntity->permanentDeath() && !game_exit ) { + // If an action handler execute. NB: MUST BE DONE BEFORE ANY THING ELSE PROFILE CRASH!!!!!!!!!!!!!!!!! + testLaunchProfile(); + + // Test and may run a VBLock profile (only once) + testLaunchProfileVBLock(); + + // Start Bench + H_AUTO_USE ( RZ_Client_Main_Loop ) if (isBGDownloadEnabled()) { @@ -1612,11 +1141,6 @@ bool mainLoop() } { - // If an action handler execute. NB: MUST BE DONE BEFORE ANY THING ELSE PROFILE CRASH!!!!!!!!!!!!!!!!! - testLaunchProfile(); - - // Test and may run a VBLock profile (only once) - testLaunchProfileVBLock(); // Stop the Outgame music, with fade effect outgameFader.fade(); @@ -1624,10 +1148,6 @@ bool mainLoop() // update quit feature updateGameQuitting(); - // Start Bench - H_AUTO_USE ( RZ_Client_Main_Loop ) - - // update module manager NLNET::IModuleManager::getInstance().updateModules(); @@ -1862,9 +1382,30 @@ bool mainLoop() // Update Camera Position/Orientation. CVector currViewPos = View.currentViewPos(); - MainCam.setPos(currViewPos);; - MainCam.setRotQuat(View.currentView()); - + MainCam.setTransformMode(UTransformable::RotQuat); + MainCam.setPos(currViewPos); + MainCam.setRotQuat(View.currentViewQuat()); + if (StereoHMD) + { + NLMISC::CQuat hmdOrient = StereoHMD->getOrientation(); + NLMISC::CMatrix camMatrix = MainCam.getMatrix(); + NLMISC::CMatrix hmdMatrix; + hmdMatrix.setRot(hmdOrient); + NLMISC::CMatrix posMatrix; // minimal head modeling, will be changed in the future + posMatrix.translate(StereoHMD->getEyePosition()); + NLMISC::CMatrix mat = ((camMatrix * hmdMatrix) * posMatrix); + MainCam.setPos(mat.getPos()); + MainCam.setRotQuat(mat.getRot()); + } + if (StereoDisplay) + { + StereoDisplay->updateCamera(0, &MainCam); + if (SceneRoot) + { + UCamera cam = SceneRoot->getCam(); + StereoDisplay->updateCamera(1, &cam); + } + } // see if camera is below water (useful for sort order) if (ContinentMngr.cur()) @@ -1955,9 +1496,6 @@ bool mainLoop() } - ////////////////////////// - // RENDER THE FRAME 3D // - ////////////////////////// if (!ClientCfg.Light) { CClientDate newDate(RT.getRyzomDay(), DayNightCycleHour); @@ -2044,9 +1582,6 @@ bool mainLoop() } } - // Set the matrix in 3D Mode. - Driver->setMatrixMode3D(MainCam); - // R2ED pre render update if (ClientCfg.R2EDEnabled) @@ -2054,237 +1589,306 @@ bool mainLoop() R2::getEditor().updateBeforeRender(); } - - // Position the camera to prepare the render if (!ClientCfg.Light) { - // Render if(Render) { - #ifdef USE_WATER_ENV_MAP - if (WaterEnvMapRefCount > 0) // water env map needed - { - if (!WaterEnvMap) - { - CSky &sky = ContinentMngr.cur()->CurrentSky; - if (sky.getScene()) - { - WaterEnvMapSkyCam = sky.getScene()->createCamera(); // deleted in unselect - WaterEnvMapCanopyCam = SceneRoot->createCamera(); // deleted in unselect - // Create water env map if not already created - WaterEnvMap = Driver->createWaterEnvMap(); - if(WaterEnvMap) - { - WaterEnvMap->init(128, 256, ClientCfg.WaterEnvMapUpdateTime); - WaterEnvMap->setWaterEnvMapRenderCallback(&WaterEnvMapRdr); - Scene->setWaterEnvMap(WaterEnvMap); - } - } - } - WaterEnvMapRdr.CurrDate = SmoothedClientDate; - WaterEnvMapRdr.AnimationDate = SmoothedClientDate; - if (ClientCfg.R2EDEnabled && R2::getEditor().getFixedLighting()) - { - WaterEnvMapRdr.CurrDate.Hour = 12.f; - } - WaterEnvMapRdr.CurrFogColor = MainFogState.FogColor; - WaterEnvMapRdr.CurrTime = TimeInSec - FirstTimeInSec; - WaterEnvMapRdr.CurrWeather = WeatherManager.getWeatherValue(); - CSky &sky = ContinentMngr.cur()->CurrentSky; - WaterEnvMap->setAlpha(sky.getWaterEnvMapAlpha()); - Scene->updateWaterEnvMaps(TimeInSec - FirstTimeInSec); - } - #endif - renderAll(ScreenshotRequest != ScreenshotRequestNone && ClientCfg.ScreenShotFullDetail); // nb : force full detail if a screenshot is asked + // Update water env map (happens when continent changed etc) + updateWaterEnvMap(); + + // Update weather + updateWeather(); + } + } + + uint i = 0; + uint bloomStage = 0; + while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass())) + { + ++i; + /////////////////// + // SETUP CAMERAS // + /////////////////// - // for that frame and - // tmp : display height grid - //static volatile bool displayHeightGrid = true; - /*if (displayHeightGrid) - { - HeightGrid.display(*Driver); - }*/ - // display results? - if(Scene_Profile) + if (StereoDisplay) + { + // modify cameras for stereo display + const CViewport &vp = StereoDisplay->getCurrentViewport(); + Driver->setViewport(vp); + nlassert(Scene); + Scene->setViewport(vp); + if (SceneRoot) { - displaySceneProfiles(); - Scene_Profile= false; + SceneRoot->setViewport(vp); } - // Render the primitives + //MainCam.setTransformMode(UTransformable::DirectMatrix); + StereoDisplay->getCurrentMatrix(0, &MainCam); + StereoDisplay->getCurrentFrustum(0, &MainCam); + if (SceneRoot) { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - PrimFiles.display (*Driver); + // matrix updated during commitCamera from maincam + UCamera cam = SceneRoot->getCam(); + StereoDisplay->getCurrentFrustum(1, &cam); } } - else - { - Driver->clearBuffers(ClientCfg.BGColor); - } - // Draw Extra 3D Objects - Driver->setMatrixMode3D(MainCam); - Driver->setModelMatrix(CMatrix::Identity); + // Commit camera changes + commitCamera(); + + ////////////////////////// + // RENDER THE FRAME 3D // + ////////////////////////// - // Display PACS borders. - if (PACSBorders) + bool stereoRenderTarget = (StereoDisplay != NULL) && StereoDisplay->beginRenderTarget(); + + if (!StereoDisplay || StereoDisplay->wantClear()) { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - displayPACSBorders(); - displayPACSPrimitive(); + if (Render) + { + if (ClientCfg.Bloom) + { + nlassert(bloomStage == 0); + // set bloom parameters before applying bloom effect + CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); + CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); + // start bloom effect (just before the first scene element render) + CBloomEffect::instance().initBloom(); + bloomStage = 1; + } + } + + // Clear buffers + clearBuffers(); } - // display Sound box - if (SoundBox) + if (!StereoDisplay || StereoDisplay->wantScene()) { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - displaySoundBox(); + if (!ClientCfg.Light) + { + // Render + if(Render) + { + // nb : force full detail if a screenshot is asked + // todo : move outside render code + bool fullDetail = ScreenshotRequest != ScreenshotRequestNone && ClientCfg.ScreenShotFullDetail; + if (fullDetail) + { + s_ForceFullDetail.backup(); + s_ForceFullDetail.set(); + } + + // Render scene + renderScene(); + + if (fullDetail) + { + s_ForceFullDetail.restore(); + } + } + } } - // display Debug of Clusters - if (DebugClusters) + if (!StereoDisplay || StereoDisplay->wantInterface3D()) { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - displayDebugClusters(); - } + if (!ClientCfg.Light) + { + // Render + if (Render) + { + if (ClientCfg.Bloom && bloomStage == 1) + { + // End the actual bloom effect visible in the scene. + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); + CBloomEffect::instance().endBloom(); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); + bloomStage = 2; + } - } - else - { -// static UTextureFile *backgroundBitmap = NULL; -// if (backgroundBitmap == NULL) -// backgroundBitmap = Driver->createTextureFile("temp_background.tga"); -// Driver->setMatrixMode2D11(); -// Driver->drawBitmap (0.f, 0.f, 1024.f/1024.f, 1024.f/768.f, (UTexture&)*backgroundBitmap); -// Driver->setMatrixMode3D(MainCam); - - Driver->clearBuffers(CRGBA (0,0,0,0)); - displayPACSBorders(); - displayPACSPrimitive(); - } + // for that frame and + // tmp : display height grid + //static volatile bool displayHeightGrid = true; + /*if (displayHeightGrid) + { + HeightGrid.display(*Driver); + }*/ + // display results? + if(Scene_Profile) + { + displaySceneProfiles(); + Scene_Profile= false; + } + // Render the primitives + { + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + PrimFiles.display (*Driver); + } + } /* if (Render) */ - if (!ClientCfg.Light && !Landscape) - { - displayPACSBorders(); - } + // Draw Extra 3D Objects + Driver->setMatrixMode3D(MainCam); + Driver->setModelMatrix(CMatrix::Identity); + + // Display PACS borders. + if (PACSBorders) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + displayPACSBorders(); + displayPACSPrimitive(); + } - // Display some things not in the scene like the name, the entity path, etc. - EntitiesMngr.updatePostRender(); + // display Sound box + if (SoundBox) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + displaySoundBox(); + } - // R2ED pre render update - if (ClientCfg.R2EDEnabled) - { - // IMPORTANT : this should be called after CEntitiesMngr::updatePostRender() because - // entity may be added / removed there ! - R2::getEditor().updateAfterRender(); - } + // display Debug of Clusters + if (DebugClusters) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + displayDebugClusters(); + } + } /* if (!ClientCfg.Light) */ + else + { + // static UTextureFile *backgroundBitmap = NULL; + // if (backgroundBitmap == NULL) + // backgroundBitmap = Driver->createTextureFile("temp_background.tga"); + // Driver->setMatrixMode2D11(); + // Driver->drawBitmap (0.f, 0.f, 1024.f/1024.f, 1024.f/768.f, (UTexture&)*backgroundBitmap); + // Driver->setMatrixMode3D(MainCam); + + Driver->clearBuffers(CRGBA (0,0,0,0)); + displayPACSBorders(); + displayPACSPrimitive(); + } - // Update FXs (remove them). - FXMngr.update(); + if (!ClientCfg.Light && !Landscape) + { + displayPACSBorders(); + } - // Render the stat graphs if needed - { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - CGraph::render (ShowInfos); - } + // Display some things not in the scene like the name, the entity path, etc. + EntitiesMngr.updatePostRender(); - // Render in 2D Mode to display 2D Interfaces and 2D texts. - Driver->setMatrixMode2D11(); + // Render the stat graphs if needed + { + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + CGraph::render (ShowInfos); + } - // draw a big quad to represent thunder strokes - if (Render && WeatherManager.getThunderLevel() != 0.f) - { - H_AUTO_USE ( RZ_Client_Main_Loop_Render_Thunder ) - Driver->drawQuad(0, 0, 1, 1, ThunderColor); + } /* if (!StereoDisplay || StereoDisplay->wantInterface3D()) */ - // TODO : boris : add sound here ! - } + if (!StereoDisplay || StereoDisplay->wantInterface2D()) + { + // Render in 2D Mode to display 2D Interfaces and 2D texts. + Driver->setMatrixMode2D11(); - // Update the contextual menu - { - H_AUTO_USE ( RZ_Client_Main_Loop_Interface ) + // draw a big quad to represent thunder strokes + /*if (Render && WeatherManager.getThunderLevel() != 0.f) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Render_Thunder ) + Driver->drawQuad(0, 0, 1, 1, ThunderColor); - // Update the game cursor. - ContextCur.check(); - GameContextMenu.update(); + // TODO : boris : add sound here ! + // Needs more explosions + }*/ - // validate dialogs - validateDialogs(GameContextMenu); + // Update the contextual menu + { + H_AUTO_USE ( RZ_Client_Main_Loop_Interface ) - // Display interface v3 - Driver->enableFog (false); - if (!Driver->isLost()) - { - if(ShowInterface) - pIMinstance->updateFrameViews (MainCam); - if(DebugUIView) - pIMinstance->displayUIViewBBoxs(DebugUIFilter); - if(DebugUICtrl) - pIMinstance->displayUICtrlBBoxs(DebugUIFilter); - if(DebugUIGroup) - pIMinstance->displayUIGroupBBoxs(DebugUIFilter); - } + // Update the game cursor. + ContextCur.check(); + GameContextMenu.update(); - // special case in OpenGL : all scene has been display in render target, - // now, final texture is display with a quad - if(!ClientCfg.Light && ClientCfg.Bloom) - CBloomEffect::getInstance().endInterfacesDisplayBloom(); - } + // validate dialogs + validateDialogs(GameContextMenu); - { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - if (!Driver->isLost()) - { - // If show information is Active. - if(ShowInfos == 1) - displayDebug(); + // Display interface v3 + Driver->enableFog (false); + if (!Driver->isLost()) + { + if(ShowInterface) + pIMinstance->updateFrameViews (MainCam); + if(DebugUIView) + pIMinstance->displayUIViewBBoxs(DebugUIFilter); + if(DebugUICtrl) + pIMinstance->displayUICtrlBBoxs(DebugUIFilter); + if(DebugUIGroup) + pIMinstance->displayUIGroupBBoxs(DebugUIFilter); + } + + // special case in OpenGL : all scene has been display in render target, + // now, final texture is display with a quad + if (!ClientCfg.Light && ClientCfg.Bloom && Render && bloomStage == 2) + { + // End bloom effect system after drawing the 3d interface (z buffer related). + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); + CBloomEffect::instance().endInterfacesDisplayBloom(); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); + bloomStage = 0; + } + } + + { + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + if (!Driver->isLost()) + { + // If show information is Active. + if(ShowInfos == 1) + displayDebug(); - // If show information is Active. - if(ShowInfos == 2) - displayNetDebug(); + // If show information is Active. + if(ShowInfos == 2) + displayNetDebug(); - // If show information is Active. - if(ShowInfos == 4) - displayDebugFps(); + // If show information is Active. + if(ShowInfos == 4) + displayDebugFps(); - // If show information is Active. - if(ShowInfos == 5) - displayDebugUIUnderMouse(); + // If show information is Active. + if(ShowInfos == 5) + displayDebugUIUnderMouse(); - // If show information is Active. - displayStreamingDebug(); + // If show information is Active. + displayStreamingDebug(); - // If Show Help is active -> Display an help. - if(ShowHelp) - displayHelp(); + // If Show Help is active -> Display an help. + if(ShowHelp) + displayHelp(); - // Yoyo: indicate profiling state - if( Profiling ) - displaySpecialTextProgress("Profiling"); + // Yoyo: indicate profiling state + if( Profiling ) + displaySpecialTextProgress("Profiling"); - // Display frame rate + // Display frame rate - // Create a shadow when displaying a text. - TextContext->setShaded(true); - // Set the font size. - TextContext->setFontSize(10); - // Set the text color - TextContext->setColor(CRGBA(255,255,255)); + // Create a shadow when displaying a text. + TextContext->setShaded(true); + // Set the font size. + TextContext->setFontSize(10); + // Set the text color + TextContext->setColor(CRGBA(255,255,255)); - // temporary values for conversions - float x, y, width, height; + // temporary values for conversions + float x, y, width, height; - for(uint i = 0; i < ClientCfg.Logos.size(); i++) - { - std::vector res; - explode(ClientCfg.Logos[i],std::string(":"), res); - if(res.size()==9 && idrawBitmap(x/(float)ClientCfg.Width, y/(float)ClientCfg.Height, width/(float)ClientCfg.Width, height/(float)ClientCfg.Height, *LogoBitmaps[i]); + for(uint i = 0; i < ClientCfg.Logos.size(); i++) + { + std::vector res; + explode(ClientCfg.Logos[i],std::string(":"), res); + if(res.size()==9 && idrawBitmap(x/(float)ClientCfg.Width, y/(float)ClientCfg.Height, width/(float)ClientCfg.Width, height/(float)ClientCfg.Height, *LogoBitmaps[i]); + } + } } } @@ -2305,6 +1909,17 @@ bool mainLoop() } } + // R2ED post render update + if (ClientCfg.R2EDEnabled) + { + // IMPORTANT : this should be called after CEntitiesMngr::updatePostRender() because + // entity may be added / removed there ! + R2::getEditor().updateAfterRender(); + } + + // Update FXs (remove them). + FXMngr.update(); + // Detect disconnection / server down: display information text // but keep the rendering so that the player can remember where he is // and what he was doing. He can't move because the connection quality returns false. @@ -2318,211 +1933,216 @@ bool mainLoop() // from the EGS, resume the sequence because the EGS is down and won't reply. FarTP.onServerQuitOk(); } - } - } - - // Yoyo: MovieShooter. - if(MovieShooterSaving) - { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - // Add the buffer frame to the movie. - if(!MovieShooter.addFrame(TimeInSec, Driver)) - { - // Fail to add the frame => abort. - endMovieShooting(); - } - else - { - // Ok, just add a display. - displaySpecialTextProgress("MovieShooting"); - } - } + // Yoyo: MovieShooter. + if(MovieShooterSaving) + { + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - if (isRecordingCamera()) - { - displaySpecialTextProgress("CameraRecording"); - } + // Add the buffer frame to the movie. + if(!MovieShooter.addFrame(TimeInSec, Driver)) + { + // Fail to add the frame => abort. + endMovieShooting(); + } + else + { + // Ok, just add a display. + displaySpecialTextProgress("MovieShooting"); + } + } - // Temp for weather test - if (ClientCfg.ManualWeatherSetup && ContinentMngr.cur() && ContinentMngr.cur()->WeatherFunction) - { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - static float displayHourDelta = 0.04f; // static for edition during debug.. + if (isRecordingCamera()) + { + displaySpecialTextProgress("CameraRecording"); + } - // Display weather function - if (DisplayWeatherFunction) - { - uint64 currDay = RT.getRyzomDay(); - float currHour = DayNightCycleHour; - float singleHourDelta = fmodf(currHour, 1.f); - uint32 wndWidth, wndHeight; - Driver->getWindowSize(wndWidth, wndHeight); - Driver->setMatrixMode2D(CFrustum(0, 800, 600, 0, 0, 1, false)); - const float lineHeight = 100.f; - - // draw the weather function - for(uint x = 0; x < wndWidth; ++x) + // Temp for weather test + if (ClientCfg.ManualWeatherSetup && ContinentMngr.cur() && ContinentMngr.cur()->WeatherFunction) { - float weatherValue; - if(ContinentMngr.cur()) - weatherValue = ::getBlendedWeather(currDay, currHour, *WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction); - else - weatherValue = ::getBlendedWeather(currDay, currHour, *WeatherFunctionParams, 0); + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + static float displayHourDelta = 0.04f; // static for edition during debug.. - NLMISC::clamp(weatherValue, 0.f, 1.f); - CRGBA seasonToColor[EGSPD::CSeason::Invalid] = + // Display weather function + if (DisplayWeatherFunction) { - CRGBA::Green, - CRGBA::Yellow, - CRGBA::Red, - CRGBA::Blue - }; - Driver->drawLine((float) x, 0.f, (float) x, lineHeight * weatherValue, seasonToColor[CRyzomTime::getSeasonByDay((uint32)currDay)]); - currHour += displayHourDelta; - if (currHour >= 24.f) + uint64 currDay = RT.getRyzomDay(); + float currHour = DayNightCycleHour; + float singleHourDelta = fmodf(currHour, 1.f); + uint32 wndWidth, wndHeight; + Driver->getWindowSize(wndWidth, wndHeight); + Driver->setMatrixMode2D(CFrustum(0, 800, 600, 0, 0, 1, false)); + const float lineHeight = 100.f; + + // draw the weather function + for(uint x = 0; x < wndWidth; ++x) + { + float weatherValue; + if(ContinentMngr.cur()) + weatherValue = ::getBlendedWeather(currDay, currHour, *WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction); + else + weatherValue = ::getBlendedWeather(currDay, currHour, *WeatherFunctionParams, 0); + + NLMISC::clamp(weatherValue, 0.f, 1.f); + CRGBA seasonToColor[EGSPD::CSeason::Invalid] = + { + CRGBA::Green, + CRGBA::Yellow, + CRGBA::Red, + CRGBA::Blue + }; + Driver->drawLine((float) x, 0.f, (float) x, lineHeight * weatherValue, seasonToColor[CRyzomTime::getSeasonByDay((uint32)currDay)]); + currHour += displayHourDelta; + if (currHour >= 24.f) + { + ++currDay; + currHour -= 24.f; + } + singleHourDelta += displayHourDelta; + if (singleHourDelta >= 1.f) + { + singleHourDelta -= 1.f; + Driver->drawLine((float) x, 100.f, (float) x, 130, CRGBA::Red); + } + } + + if(ContinentMngr.cur()) + { + // draw lines for current weather setups + uint numWeatherSetups = ContinentMngr.cur()->WeatherFunction[CurrSeason].getNumWeatherSetups(); + for (uint y = 0; y < numWeatherSetups; ++y) + { + float py = lineHeight * (y / (float) numWeatherSetups); + Driver->drawLine(0.f, py, 800.f, py, CRGBA::Magenta); + } + } + } + + // Ctrl+ & Ctrl- change the weather value + if (Actions.valide ("inc_time")) { - ++currDay; - currHour -= 24.f; + ManualWeatherValue += DT * 0.04f; } - singleHourDelta += displayHourDelta; - if (singleHourDelta >= 1.f) + if (Actions.valide ("dec_time")) { - singleHourDelta -= 1.f; - Driver->drawLine((float) x, 100.f, (float) x, 130, CRGBA::Red); + ManualWeatherValue -= DT * 0.04f; } - } + NLMISC::clamp(ManualWeatherValue, 0.f, 1.f); - if(ContinentMngr.cur()) - { - // draw lines for current weather setups - uint numWeatherSetups = ContinentMngr.cur()->WeatherFunction[CurrSeason].getNumWeatherSetups(); - for (uint y = 0; y < numWeatherSetups; ++y) + if (ForcedDayNightCycleHour < 0) // if time is forced then can't change it manually ... { - float py = lineHeight * (y / (float) numWeatherSetups); - Driver->drawLine(0.f, py, 800.f, py, CRGBA::Magenta); + // Ctrl-K increase hour + if (Actions.valide ("inc_hour")) + { + RT.increaseTickOffset( (uint32)(2000 * displayHourDelta) ); + RT.updateRyzomClock(NetMngr.getCurrentServerTick(), ryzomGetLocalTime() * 0.001); + } + + // Ctrl-L decrease hour + if (Actions.valide ("dec_hour")) + { + RT.decreaseTickOffset( (uint32)(2000 * displayHourDelta) ); + RT.updateRyzomClock(NetMngr.getCurrentServerTick(), ryzomGetLocalTime() * 0.001); + CTimedFXManager::getInstance().setDate(CClientDate(RT.getRyzomDay(), (float) RT.getRyzomTime())); + if (IGCallbacks) + { + IGCallbacks->changeSeason(); // the season doesn't change, but this force fxs to be recreated + } + } } - } - } - // Ctrl+ & Ctrl- change the weather value - if (Actions.valide ("inc_time")) - { - ManualWeatherValue += DT * 0.04f; - } - if (Actions.valide ("dec_time")) - { - ManualWeatherValue -= DT * 0.04f; - } - NLMISC::clamp(ManualWeatherValue, 0.f, 1.f); + // Ctrl-M generate statistics in a file + /* + if (Actions.valide ("weather_stats")) + { + // Only usable if there is a continent loaded. + if(ContinentMngr.cur()) + CPredictWeather::generateWeatherStats("weather_stats.csv", WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction); + }*/ - if (ForcedDayNightCycleHour < 0) // if time is forced then can't change it manually ... - { - // Ctrl-K increase hour - if (Actions.valide ("inc_hour")) - { - RT.increaseTickOffset( (uint32)(2000 * displayHourDelta) ); - RT.updateRyzomClock(NetMngr.getCurrentServerTick(), ryzomGetLocalTime() * 0.001); + // Ctrl-B decrease display factor + if (Actions.valide ("dec_display_factor")) + { + displayHourDelta *= 0.90f; + } + // Ctrl-J increase display factor + if (Actions.valide ("inc_display_factor")) + { + displayHourDelta *= 1.1f; + displayHourDelta = std::min(1000.f, displayHourDelta); + } } - // Ctrl-L decrease hour - if (Actions.valide ("dec_hour")) + // Ctrl-AltGR-Z show timed FXs + if (ShowTimedFX) { - RT.decreaseTickOffset( (uint32)(2000 * displayHourDelta) ); - RT.updateRyzomClock(NetMngr.getCurrentServerTick(), ryzomGetLocalTime() * 0.001); - CTimedFXManager::getInstance().setDate(CClientDate(RT.getRyzomDay(), (float) RT.getRyzomTime())); - if (IGCallbacks) + if (!Driver->isLost()) { - IGCallbacks->changeSeason(); // the season doesn't change, but this force fxs to be recreated + CTimedFXManager::getInstance().displayFXBoxes(ShowTimedFXMode); } } - } - - // Ctrl-M generate statistics in a file - /* - if (Actions.valide ("weather_stats")) - { - // Only usable if there is a continent loaded. - if(ContinentMngr.cur()) - CPredictWeather::generateWeatherStats("weather_stats.csv", WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction); - }*/ - - // Ctrl-B decrease display factor - if (Actions.valide ("dec_display_factor")) - { - displayHourDelta *= 0.90f; - } - // Ctrl-J increase display factor - if (Actions.valide ("inc_display_factor")) - { - displayHourDelta *= 1.1f; - displayHourDelta = std::min(1000.f, displayHourDelta); - } - } - // Ctrl-AltGR-Z show timed FXs - if (ShowTimedFX) - { - if (!Driver->isLost()) - { - CTimedFXManager::getInstance().displayFXBoxes(ShowTimedFXMode); - } - } + #if !FINAL_VERSION + CVector2f camPos(Scene->getCam().getPos().x, Scene->getCam().getPos().y); + if (!ClientCfg.Light) + { + if (DisplayMicroLifeZones) + { + CMicroLifeManager::getInstance().renderMLZones(camPos); + } + } + if (DisplayWaterMap) + { + if (ContinentMngr.cur()) + { + ContinentMngr.cur()->WaterMap.render(camPos); + } + } + #endif -#if !FINAL_VERSION - CVector2f camPos(Scene->getCam().getPos().x, Scene->getCam().getPos().y); - if (!ClientCfg.Light) - { - if (DisplayMicroLifeZones) - { - CMicroLifeManager::getInstance().renderMLZones(camPos); - } - } - if (DisplayWaterMap) - { - if (ContinentMngr.cur()) - { - ContinentMngr.cur()->WaterMap.render(camPos); - } - } - #endif + #ifdef NL_DEBUG + if (!ClientCfg.Light) + { + if (DisplayMicroLifeActiveTiles) + { + CMicroLifeManager::getInstance().renderActiveTiles(); + } + } + #endif + // tmp : debug of ground fxs + //TestGroundFX.displayFXBoxes(); - #ifdef NL_DEBUG - if (!ClientCfg.Light) - { - if (DisplayMicroLifeActiveTiles) + // Temp for sound debug { - CMicroLifeManager::getInstance().renderActiveTiles(); - } - } - #endif - // tmp : debug of ground fxs - //TestGroundFX.displayFXBoxes(); + H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) - // Temp for sound debug - { - H_AUTO_USE ( RZ_Client_Main_Loop_Debug ) + if (SoundMngr != 0) + { + static bool drawSound = false; + static float camHeigh = 150.0f; - if (SoundMngr != 0) - { - static bool drawSound = false; - static float camHeigh = 150.0f; + #if FINAL_VERSION + if (ClientCfg.ExtendedCommands) + #endif + if (Actions.valide ("draw_sound")) + drawSound = !drawSound; -#if FINAL_VERSION - if (ClientCfg.ExtendedCommands) -#endif - if (Actions.valide ("draw_sound")) - drawSound = !drawSound; + if (Actions.valide ("inc_camera_height")) + camHeigh -= 10.0f; + if (Actions.valide ("dec_camera_height")) + camHeigh += 10.0f; - if (Actions.valide ("inc_camera_height")) - camHeigh -= 10.0f; - if (Actions.valide ("dec_camera_height")) - camHeigh += 10.0f; + if (drawSound) + SoundMngr->drawSounds(camHeigh); + } + } + } /* if (!StereoDisplay || StereoDisplay->wantInterface2D()) */ - if (drawSound) - SoundMngr->drawSounds(camHeigh); + if (StereoDisplay) + { + StereoDisplay->endRenderTarget(); } - } + } /* stereo pass */ // Draw to screen. static CQuat MainCamOri; @@ -2581,169 +2201,11 @@ bool mainLoop() // TMP TMP static volatile bool dumpValidPolys = false; - if (dumpValidPolys) - { - struct CPolyDisp : public CInterfaceElementVisitor - { - virtual void visitCtrl(CCtrlBase *ctrl) - { - CCtrlPolygon *cp = dynamic_cast(ctrl); - if (cp) - { - sint32 cornerX, cornerY; - cp->getParent()->getCorner(cornerX, cornerY, cp->getParentPosRef()); - for(sint32 y = 0; y < (sint32) Screen.getHeight(); ++y) - { - for(sint32 x = 0; x < (sint32) Screen.getWidth(); ++x) - { - if (cp->contains(CVector2f((float) (x - cornerX), (float) (y - cornerY)))) - { - ((CRGBA *) &Screen.getPixels()[0])[x + (Screen.getHeight() - 1 - y) * Screen.getWidth()] = CRGBA::Magenta; - } - } - } - } - } - CBitmap Screen; - } polyDisp; - Driver->getBuffer(polyDisp.Screen); - CInterfaceManager::getInstance()->visit(&polyDisp); - COFile output("poly.tga"); - polyDisp.Screen.writeTGA(output); - dumpValidPolys = false; - }; + if (dumpValidPolys) { tempDumpValidPolys(); dumpValidPolys = false; } // TMP TMP static volatile bool dumpColPolys = false; - if (dumpColPolys) - { - CPackedWorld *pw = R2::getEditor().getIslandCollision().getPackedIsland(); - if (pw) - { - static CMaterial material; - static CMaterial wiredMaterial; - static CMaterial texturedMaterial; - static CVertexBuffer vb; - static bool initDone = false; - if (!initDone) - { - vb.setVertexFormat(CVertexBuffer::PositionFlag); - vb.setPreferredMemory(CVertexBuffer::AGPVolatile, false); - material.initUnlit(); - material.setDoubleSided(true); - material.setZFunc(CMaterial::lessequal); - wiredMaterial.initUnlit(); - wiredMaterial.setDoubleSided(true); - wiredMaterial.setZFunc(CMaterial::lessequal); - wiredMaterial.setColor(CRGBA(255, 255, 255, 250)); - wiredMaterial.texEnvOpAlpha(0, CMaterial::Replace); - wiredMaterial.texEnvArg0Alpha(0, CMaterial::Diffuse, CMaterial::SrcAlpha); - wiredMaterial.setBlend(true); - wiredMaterial.setBlendFunc(CMaterial::srcalpha, CMaterial::invsrcalpha); - texturedMaterial.initUnlit(); - texturedMaterial.setDoubleSided(true); - texturedMaterial.setZFunc(CMaterial::lessequal); - initDone = true; - } - // just add a projected texture - R2::getEditor().getIslandCollision().loadEntryPoints(); - R2::CScenarioEntryPoints &sep = R2::CScenarioEntryPoints::getInstance(); - CVectorD playerPos = UserEntity->pos(); - R2::CScenarioEntryPoints::CCompleteIsland *island = sep.getCompleteIslandFromCoords(CVector2f((float) playerPos.x, (float) playerPos.y)); - static CSString currIsland; - if (island && island->Island != currIsland) - { - currIsland = island->Island; - CTextureFile *newTex = new CTextureFile(currIsland + "_sp.tga"); - newTex->setWrapS(ITexture::Clamp); - newTex->setWrapT(ITexture::Clamp); - texturedMaterial.setTexture(0, newTex); - texturedMaterial.texEnvOpRGB(0, CMaterial::Replace); - texturedMaterial.texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor); - texturedMaterial.setTexCoordGen(0, true); - texturedMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace); - CMatrix mat; - CVector scale((float) (island->XMax - island->XMin), - (float) (island->YMax - island->YMin), 0.f); - scale.x = 1.f / favoid0(scale.x); - scale.y = 1.f / favoid0(scale.y); - scale.z = 0.f; - mat.setScale(scale); - mat.setPos(CVector(- island->XMin * scale.x, - island->YMin * scale.y, 0.f)); - // - CMatrix uvScaleMat; - // - uint texWidth = (uint) (island->XMax - island->XMin); - uint texHeight = (uint) (island->YMax - island->YMin); - float UScale = (float) texWidth / raiseToNextPowerOf2(texWidth); - float VScale = (float) texHeight / raiseToNextPowerOf2(texHeight); - // - uvScaleMat.setScale(CVector(UScale, - VScale, 0.f)); - uvScaleMat.setPos(CVector(0.f, VScale, 0.f)); - // - texturedMaterial.enableUserTexMat(0, true); - texturedMaterial.setUserTexMat(0, uvScaleMat * mat); - } - const CFrustum &frust = MainCam.getFrustum(); - - // - IDriver *driver = ((CDriverUser *) Driver)->getDriver(); - - driver->enableFog(true); - const CRGBA clearColor = CRGBA(0, 0, 127, 0); - driver->setupFog(frust.Far * 0.8f, frust.Far, clearColor); - CViewport vp; - vp.init(0.f, 0.f, 1.f, 1.f); - driver->setupViewport(vp); - CScissor scissor; - viewportToScissor(vp, scissor); - driver->setupScissor(scissor); - // - driver->setFrustum(frust.Left, frust.Right, frust.Bottom, frust.Top, frust.Near, frust.Far, frust.Perspective); - driver->setupViewMatrix(MainCam.getMatrix().inverted()); - driver->setupModelMatrix(CMatrix::Identity); - // - // - const CVector localFrustCorners[8] = - { - CVector(frust.Left, frust.Near, frust.Top), - CVector(frust.Right, frust.Near, frust.Top), - CVector(frust.Right, frust.Near, frust.Bottom), - CVector(frust.Left, frust.Near, frust.Bottom), - CVector(frust.Left * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near), - CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near), - CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near), - CVector(frust.Left * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near) - }; - // roughly compute covered zones - // - /* - sint frustZoneMinX = INT_MAX; - sint frustZoneMaxX = INT_MIN; - sint frustZoneMinY = INT_MAX; - sint frustZoneMaxY = INT_MIN; - for(uint k = 0; k < sizeofarray(localFrustCorners); ++k) - { - CVector corner = camMat * localFrustCorners[k]; - sint zoneX = (sint) (corner.x / 160.f) - zoneMinX; - sint zoneY = (sint) floorf(corner.y / 160.f) - zoneMinY; - frustZoneMinX = std::min(frustZoneMinX, zoneX); - frustZoneMinY = std::min(frustZoneMinY, zoneY); - frustZoneMaxX = std::max(frustZoneMaxX, zoneX); - frustZoneMaxY = std::max(frustZoneMaxY, zoneY); - } - */ - - const uint TRI_BATCH_SIZE = 10000; // batch size for rendering - static std::vector zones; - zones.clear(); - pw->getZones(zones); - for(uint k = 0; k < zones.size(); ++k) - { - zones[k]->render(vb, *driver, texturedMaterial, wiredMaterial, MainCam.getMatrix(), TRI_BATCH_SIZE, localFrustCorners); - } - } - } + if (dumpColPolys) { tempDumpColPolys(); } if (ClientCfg.R2EDEnabled) { @@ -2898,6 +2360,9 @@ bool mainLoop() frameToSkip--; } + /////////////// + // FAR_TP -> // + /////////////// // Enter a network loop during the FarTP process, without doing the whole real main loop. // This code must remain at the very end of the main loop. if(LoginSM.getCurrentState() == CLoginStateMachine::st_enter_far_tp_main_loop) @@ -2981,7 +2446,10 @@ bool mainLoop() connectionState = NetMngr.getConnectionState(); CLuaManager::getInstance().executeLuaScript("game:onFarTpEnd()"); - } + } + /////////////// + // <- FAR_TP // + /////////////// } // end of main loop @@ -3049,690 +2517,6 @@ bool mainLoop() return ryzom_exit || (Driver == NULL) || (!Driver->isActive ()); }// mainLoop // -//--------------------------------------------------- -// displayDebug : -// Display some debug infos. -//--------------------------------------------------- -void displayDebugFps() -{ - float lineStep = ClientCfg.DebugLineStep; - float line; - - // Initialize Pen // - //----------------// - // Create a shadow when displaying a text. - TextContext->setShaded(true); - // Set the font size. - TextContext->setFontSize(ClientCfg.DebugFontSize); - // Set the text color - TextContext->setColor(ClientCfg.DebugFontColor); - - // TOP LEFT // - //----------// - TextContext->setHotSpot(UTextContext::TopLeft); - line = 0.9f; - // Ms per frame - { - float spf = smoothFPS.getSmoothValue (); - // Ms per frame - TextContext->printfAt(0.1f, line, "FPS %.1f ms - %.1f fps", spf*1000, 1.f/spf); - line-= lineStep; - // More Smoothed Ms per frame - spf = moreSmoothFPS.getSmoothValue (); - TextContext->printfAt(0.1f, line, "Smoothed FPS %.1f ms - %.1f fps", spf*1000, 1.f/spf); - line-= lineStep; - } -} - -static NLMISC::CRefPtr HighlightedDebugUI; - -// displayDebug : -// Display information about ui elements that are under the mouse -//--------------------------------------------------- -void displayDebugUIUnderMouse() -{ - float lineStep = ClientCfg.DebugLineStep; - float line; - - // Initialize Pen // - //----------------// - // Create a shadow when displaying a text. - TextContext->setShaded(true); - // Set the font size. - TextContext->setFontSize(ClientCfg.DebugFontSize); - - - - // TOP LEFT // - //----------// - TextContext->setHotSpot(UTextContext::TopLeft); - line = 0.9f; - - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - // for now only accessible with R2ED - if (ClientCfg.R2EDEnabled) - { - TextContext->setColor(CRGBA::Cyan); - TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+A) to cycle prev"); - line-= lineStep; - TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+Q) to cycle next"); - line-= lineStep; - TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+W) to inspect element"); - line-= 2 * lineStep; - } - // - const vector &rICL = CWidgetManager::getInstance()->getCtrlsUnderPointer (); - const vector &rIGL = CWidgetManager::getInstance()->getGroupsUnderPointer (); - // If previous highlighted element is found in the list, then keep it, else reset to first element - if (std::find(rICL.begin(), rICL.end(), HighlightedDebugUI) == rICL.end() && - std::find(rIGL.begin(), rIGL.end(), HighlightedDebugUI) == rIGL.end()) - { - if (!rICL.empty()) - { - HighlightedDebugUI = rICL[0]; - } - else - if (!rIGL.empty()) - { - HighlightedDebugUI = rIGL[0]; - } - else - { - HighlightedDebugUI = NULL; - } - } - // - TextContext->setColor(CRGBA::Green); - TextContext->printfAt(0.1f, line, "Controls under cursor "); - line -= lineStep * 1.4f; - TextContext->printfAt(0.1f, line, "----------------------"); - line -= lineStep; - for(uint k = 0; k < rICL.size(); ++k) - { - if (rICL[k]) - { - TextContext->setColor(rICL[k] != HighlightedDebugUI ? ClientCfg.DebugFontColor : CRGBA::Red); - TextContext->printfAt(0.1f, line, "id = %s, address = 0x%p, parent = 0x%p", rICL[k]->getId().c_str(), rICL[k], rICL[k]->getParent()); - } - else - { - TextContext->setColor(CRGBA::Blue); - TextContext->printfAt(0.1f, line, " control found !!!"); - } - line-= lineStep; - } - // - TextContext->setColor(CRGBA::Green); - TextContext->printfAt(0.1f, line, "Groups under cursor "); - line -= lineStep * 1.4f; - TextContext->printfAt(0.1f, line, "----------------------"); - line-= lineStep; - for(uint k = 0; k < rIGL.size(); ++k) - { - if (rIGL[k]) - { - TextContext->setColor(rIGL[k] != HighlightedDebugUI ? ClientCfg.DebugFontColor : CRGBA::Red); - TextContext->printfAt(0.1f, line, "id = %s, address = 0x%p, parent = 0x%p", rIGL[k]->getId().c_str(), rIGL[k], rIGL[k]->getParent()); - } - else - { - TextContext->setColor(CRGBA::Blue); - TextContext->printfAt(0.1f, line, " group found !!!"); - } - line-= lineStep; - } -} - - - -// get all element under the mouse in a single vector -static void getElementsUnderMouse(vector &ielem) -{ - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - const vector &rICL = CWidgetManager::getInstance()->getCtrlsUnderPointer(); - const vector &rIGL = CWidgetManager::getInstance()->getGroupsUnderPointer(); - ielem.clear(); - ielem.insert(ielem.end(), rICL.begin(), rICL.end()); - ielem.insert(ielem.end(), rIGL.begin(), rIGL.end()); -} - -class CHandlerDebugUiPrevElementUnderMouse : public IActionHandler -{ - virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) - { - vector ielem; - getElementsUnderMouse(ielem); - for(uint k = 0; k < ielem.size(); ++k) - { - if (HighlightedDebugUI == ielem[k]) - { - HighlightedDebugUI = ielem[k == 0 ? ielem.size() - 1 : k - 1]; - return; - } - } - } -}; -REGISTER_ACTION_HANDLER( CHandlerDebugUiPrevElementUnderMouse, "debug_ui_prev_element_under_mouse"); - -class CHandlerDebugUiNextElementUnderMouse : public IActionHandler -{ - virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) - { - vector ielem; - getElementsUnderMouse(ielem); - for(uint k = 0; k < ielem.size(); ++k) - { - if (HighlightedDebugUI == ielem[k]) - { - HighlightedDebugUI = ielem[(k + 1) % ielem.size()]; - return; - } - } - } -}; -REGISTER_ACTION_HANDLER( CHandlerDebugUiNextElementUnderMouse, "debug_ui_next_element_under_mouse"); - -class CHandlerDebugUiDumpElementUnderMouse : public IActionHandler -{ - virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) - { - if (HighlightedDebugUI == NULL) return; - CLuaState *lua = CLuaManager::getInstance().getLuaState(); - if (!lua) return; - CLuaStackRestorer lsr(lua, 0); - CLuaIHM::pushUIOnStack(*lua, HighlightedDebugUI); - lua->pushGlobalTable(); - CLuaObject env(*lua); - env["inspect"].callNoThrow(1, 0); - } -}; -REGISTER_ACTION_HANDLER( CHandlerDebugUiDumpElementUnderMouse, "debug_ui_inspect_element_under_mouse"); - - -//--------------------------------------------------- -// displayDebug : -// Display some debug infos. -//--------------------------------------------------- -void displayDebug() -{ - float lineStep = ClientCfg.DebugLineStep; - float line; - - // Initialize Pen // - //----------------// - // Create a shadow when displaying a text. - TextContext->setShaded(true); - // Set the font size. - TextContext->setFontSize(ClientCfg.DebugFontSize); - // Set the text color - TextContext->setColor(ClientCfg.DebugFontColor); - - // TOP LEFT // - //----------// - TextContext->setHotSpot(UTextContext::TopLeft); - line = 0.9f; - // FPS and Ms per frame - { - // smooth across frames. - double deltaTime = smoothFPS.getSmoothValue (); - // FPS and Ms per frame - if(deltaTime != 0.f) - TextContext->printfAt(0.f, line,"%.1f fps", 1.f/deltaTime); - else - TextContext->printfAt(0.f, line,"%.1f fps", 0.f); - TextContext->printfAt(0.1f, line, "%d ms", (uint)(deltaTime*1000)); - } - line -= lineStep; - line -= lineStep; - - // USER - // Front - TextContext->printfAt(0.0f, line, " %f (%f,%f,%f) front", atan2(UserEntity->front().y, UserEntity->front().x), UserEntity->front().x, UserEntity->front().y, UserEntity->front().z); - line -= lineStep; - // Dir - TextContext->printfAt(0.0f, line, " %f (%f,%f,%f) dir", atan2(UserEntity->dir().y, UserEntity->dir().x), UserEntity->dir().x, UserEntity->dir().y, UserEntity->dir().z); - line -= lineStep; - // NB Stage - TextContext->printfAt(0.0f, line, " NB Stage: %d", UserEntity->nbStage()); - line -= lineStep; - // NB Animation FXs still remaining in the remove list. - TextContext->printfAt(0.0f, line, " NB FXs to remove: %d", UserEntity->nbAnimFXToRemove()); - line -= lineStep; - // Mode. - TextContext->printfAt(0.0f, line, " Mode: %d (%s)", (sint)UserEntity->mode(), MBEHAV::modeToString(UserEntity->mode()).c_str()); - line -= lineStep; - // Behaviour. - TextContext->printfAt(0.0f, line, " Behaviour: %d (%s)", (sint)UserEntity->behaviour(), MBEHAV::behaviourToString(UserEntity->behaviour()).c_str()); - line -= lineStep; - // Display the target mount. - TextContext->printfAt(0.0f, line, " Mount: %d", UserEntity->mount()); - line -= lineStep; - // Display the target rider. - TextContext->printfAt(0.0f, line, " Rider: %d", UserEntity->rider()); - line -= lineStep; - // Display the current animation name. - TextContext->printfAt(0.0f, line, " Current Animation Name: %s", UserEntity->currentAnimationName().c_str()); - line -= lineStep; - // Display the current move animation set name. - TextContext->printfAt(0.0f, line, " Current AnimationSet Name (MOVE): %s", UserEntity->currentAnimationSetName(MOVE).c_str()); - line -= lineStep; - // Display Missing Animations - if(::CAnimation::MissingAnim.empty() == false) - { - TextContext->printfAt(0.0f, line, " '%u' Missing Animations, 1st: '%s'", ::CAnimation::MissingAnim.size(), (*(::CAnimation::MissingAnim.begin())).c_str()); - line -= lineStep; - } - // Display Missing LoD - if(LodCharactersNotFound.empty() == false) - { - TextContext->printfAt(0.0f, line, " '%u' Missing LoD, 1st: '%s'", LodCharactersNotFound.size(), (*(LodCharactersNotFound.begin())).c_str()); - line -= lineStep; - } - - // Watched Entity - line -= lineStep; - // Now Displaying the selection. - TextContext->printfAt(0.0f, line, "--*** Watched entity ***--"); - line -= lineStep; - // Display information about the debug entity slot. - if(WatchedEntitySlot != CLFECOMMON::INVALID_SLOT) - { - // Get a pointer on the target. - CEntityCL *watchedEntity = EntitiesMngr.entity(WatchedEntitySlot); - if(watchedEntity) - { - // Display Debug Information about the Selection. - watchedEntity->displayDebug(0.0f, line, -lineStep); - - // Distance of the target - CVectorD diffvector = UserEntity->pos() - watchedEntity->pos(); - TextContext->printfAt(0.0f, line, " Distance: %10.2f (Manhattan: %.2f)", diffvector.norm(), fabs(diffvector.x) + fabs(diffvector.y) ); - line -= lineStep; - } - // Target not allocated - else - { - TextContext->printfAt(0.0f, line, "Not allocated (%d)", WatchedEntitySlot); - line -= lineStep; - } - } - // No Target - else - { - TextContext->printfAt(0.0f, line, "None"); - line -= lineStep; - } - - /* Ca rame grave ! - - uint nMem = NLMEMORY::GetAllocatedMemory(); - line -= lineStep; - TextContext->printfAt(0.0f, line, "Mem Used: %d",nMem);*/ - - // 3D Filters information: -#ifdef _PROFILE_ON_ - line-= lineStep; - TextContext->printfAt(0.0f, line, "3D Filters:"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "MeshNoVP: %s", Filter3D[FilterMeshNoVP]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "MeshVP: %s", Filter3D[FilterMeshVP]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "FXs: %s", Filter3D[FilterFXs]?"Ok":"NOT RENDERED!"); - line-= lineStep; - if (Landscape) - { - TextContext->printfAt(0.0f, line, "Landscape: %s", Filter3D[FilterLandscape]?"Ok":"NOT RENDERED!"); - line-= lineStep; - } - else - { - TextContext->printfAt(0.0f, line, "Landscape not enabled"); - } - TextContext->printfAt(0.0f, line, "Vegetable: %s", Filter3D[FilterVegetable]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "Skeleton: %s", Filter3D[FilterSkeleton]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "Water: %s", Filter3D[FilterWater]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "Cloud: %s", Filter3D[FilterCloud]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "CoarseMesh: %s", Filter3D[FilterCoarseMesh]?"Ok":"NOT RENDERED!"); - line-= lineStep; - TextContext->printfAt(0.0f, line, "Sky: %s", Filter3D[FilterSky]?"Ok":"NOT RENDERED!"); - line-= lineStep; - // Materials Infos - TextContext->printfAt(0.0f, line, "SetupedMatrix: %d", Driver->profileSetupedModelMatrix() ); - line-= lineStep; - TextContext->printfAt(0.0f, line, "SetupedMaterials: %d", Driver->profileSetupedMaterials() ); - line-= lineStep; - // Display camera cluster system - TextContext->printfAt(0.0f, line, "ClusterSystem: %p", MainCam.getClusterSystem() ); - line-= 2 * lineStep; - // Lua stuffs - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - TextContext->printfAt(0.0f, line, "Lua mem (kb) : %d / %d", CLuaManager::getInstance().getLuaState()->getGCCount(), CLuaManager::getInstance().getLuaState()->getGCThreshold()); - line-= lineStep; - TextContext->printfAt(0.0f, line, "Lua stack size = %d", CLuaManager::getInstance().getLuaState()->getTop()); - line-= lineStep; - -#endif - - // TOP LEFT // - //-----------// - TextContext->setHotSpot(UTextContext::TopLeft); - line = 1.f; - string str; -#if FINAL_VERSION - str = "FV"; -#else - str = "DEV"; -#endif - if(ClientCfg.ExtendedCommands) - str += "_E"; - str += " "RYZOM_VERSION; - TextContext->printfAt(0.f, line, "Version %s", str.c_str()); - - // TOP MIDDLE // - //------------// - TextContext->setHotSpot(UTextContext::MiddleTop); - line = 1.f; - // Motion Mode - TextContext->printfAt(0.5f, line, "%s", UserControls.modeStr().c_str()); - line -= lineStep; - - // TOP RIGHT // - //-----------// - TextContext->setHotSpot(UTextContext::TopRight); - line = 1.f; - //// 3D Infos - // Video mem allocated. - TextContext->printfAt(1.f, line, "Video mem. : %f", Driver->profileAllocatedTextureMemory()/(1024.f*1024.f)); - line -= lineStep; - // Video mem used since last swapBuffers(). - TextContext->printfAt(1.f, line, "Video mem. since last swap buffer: %f", Driver->getUsedTextureMemory()/(1024.f*1024.f)); - line -= lineStep; - // Get the last face count asked from the main scene before reduction. - TextContext->printfAt(1.f, line, "Nb Skin Face Asked: %f", Scene->getGroupNbFaceAsked("Skin")); - line -= lineStep; - TextContext->printfAt(1.f, line, "Nb Fx Face Asked: %f", Scene->getGroupNbFaceAsked("Fx")); - line -= lineStep; - // All Triangles In - CPrimitiveProfile pIn; - CPrimitiveProfile pOut; - Driver->profileRenderedPrimitives(pIn, pOut); - TextContext->printfAt(1.f, line, "Tri In : %d", pIn.NTriangles+2*pIn.NQuads); - line -= lineStep; - // All Triangles Out - TextContext->printfAt(1.f, line, "Tri Out : %d", pOut.NTriangles+2*pIn.NQuads); - line -= lineStep; - // Current Cluster - string strPos; - // Check there is a PACS Primitive before using it. - if(UserEntity->getPrimitive() && GR) - { - UGlobalPosition gPos; - UserEntity->getPrimitive()->getGlobalPosition(gPos, dynamicWI); - string strPos = GR->getIdentifier(gPos); - } - else - strPos = "No Primitive"; - TextContext->printfAt(1.f, line, "Cluster : %s", strPos.c_str()); - line -= lineStep; - //// SOUND Infos - line -= lineStep; - if(SoundMngr) - { - TextContext->printfAt(1.f, line, "Sound source instance: %u", SoundMngr->getSourcesInstanceCount()); - line -= lineStep; - TextContext->printfAt(1.f, line, "Logical playing SoundSource: %u", SoundMngr->getMixer()->getPlayingSourcesCount ()); - line -= lineStep; - TextContext->printfAt(1.f, line, "Audio tracks: %u/%u", SoundMngr->getMixer()->getUsedTracksCount(), SoundMngr->getMixer()->getPolyphony()); - line -= lineStep; - if (SoundMngr->getMixer()->getMutedPlayingSourcesCount() > 0) - { - TextContext->printfAt(1.f, line, "Source muted: %u !", SoundMngr->getMixer()->getMutedPlayingSourcesCount()); - line -= lineStep; - } - TextContext->printfAt(1.f, line, "Samples in memory: %g MB", SoundMngr->getLoadingSamplesSize() / (1024.0f*1024.0f)); - line -= lineStep; - - } - - // BOTTOM RIGHT // - //--------------// - TextContext->setHotSpot(UTextContext::BottomRight); - line = 0.f; - //// POSITION - CVector postmp = View.viewPos(); - // Pos - TextContext->printfAt(1.f, line, "Position : %d %d %d",(int)postmp.x,(int)postmp.y,(int)postmp.z); - line += lineStep; - // Body Heading - TextContext->printfAt(1.f, line, "Front : %.2f %.2f %.2f", UserEntity->front().x, UserEntity->front().y, UserEntity->front().z); - line += lineStep; - // Speed - TextContext->printfAt(1.f, line, "Speed : %.2f", (float) UserEntity->speed()); - line += lineStep; - // Zone - if (!ClientCfg.Light) - { - if (Landscape) - { - TextContext->printfAt(1.f, line, "Zone: %s", Landscape->getZoneName(postmp).c_str()); - line += lineStep; - } - } - // Prim File - string primFile = PrimFiles.getCurrentPrimitive (); - if (!primFile.empty ()) - { - TextContext->printfAt(1.f, line, "Prim File: %s", primFile.c_str ()); - line += lineStep; - } - - //// CONNECTION - line += lineStep; - // Ryzom Day. - TextContext->printfAt(1.f, line, "Ryzom Day : %d", RT.getRyzomDay()); - line += lineStep; - // hour in the game - float dayNightCycleHour = (float)RT.getRyzomTime(); - TextContext->printfAt(1.f, line, "Ryzom Time : %2u:%02u", int(dayNightCycleHour), int((dayNightCycleHour-int(dayNightCycleHour))*60.0f)); - line += lineStep; - // light hour in the game, used to display te day/night - TextContext->printfAt(1.f, line, "Ryzom Light Time : %2u:%02u (%s)", int(DayNightCycleHour), int((DayNightCycleHour-int(DayNightCycleHour))*60.0f), LightCycleManager.getStateString().c_str()); - line += lineStep; - // Server GameCycle - TextContext->printfAt(1.f, line, "Server GameCycle : %u", (uint)NetMngr.getCurrentServerTick()); - line += lineStep; - // Current GameCycle - TextContext->printfAt(1.f, line, "Current GameCycle : %u", (uint)NetMngr.getCurrentClientTick()); - line += lineStep; - // Current GameCycle - TextContext->printfAt(1.f, line, "Ms per Cycle : %d", NetMngr.getMsPerTick()); - line += lineStep; - // Packet Loss - TextContext->printfAt(1.f, line, "Packet Loss : %.1f %%", NetMngr.getMeanPacketLoss()*100.0f); - line += lineStep; - // Packet Loss - TextContext->printfAt(1.f, line, "Packets Lost : %u", NetMngr.getTotalLostPackets()); - line += lineStep; - // Mean Upload - TextContext->printfAt(1.f, line, "Mean Upld : %.3f kbps", NetMngr.getMeanUpload()); - line += lineStep; - // Mean Download - TextContext->printfAt(1.f, line, "Mean Dnld : %.3f kbps", NetMngr.getMeanDownload()); - line += lineStep; - - // Mean Download - TextContext->printfAt(1.f, line, "Nb in Vision : %d(%d,%d,%d)", - EntitiesMngr.nbEntitiesAllocated(), - EntitiesMngr.nbUser(), - EntitiesMngr.nbPlayer(), - EntitiesMngr.nbChar()); - line += lineStep; - - // Number of database changes - TextContext->printfAt(1.f, line, "DB Changes : %u", NbDatabaseChanges ); - line += lineStep; - - // Ping - TextContext->printfAt(1.f, line, "DB Ping : %u ms", Ping.getValue()); - line += lineStep; - - - - - - // Manual weather setup - { - if(ContinentMngr.cur()) // Only usable if there is a continent loaded. - { - if (!ForceTrueWeatherValue) - { - const CWeatherFunction &wf = ContinentMngr.cur()->WeatherFunction[CurrSeason]; - float wv; - if (ClientCfg.ManualWeatherSetup) - { - wv = std::max(wf.getNumWeatherSetups() - 1, 0u) * ManualWeatherValue; - } - else - { - wv = std::max(wf.getNumWeatherSetups() - 1, 0u) * ::getBlendedWeather(RT.getRyzomDay(), RT.getRyzomTime(), *WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction); - } - const CWeatherSetup *ws = wf.getWeatherSetup((uint) floorf(wv)); - std::string name0 = ws ? NLMISC::CStringMapper::unmap(ws->SetupName) : "???"; - ws = wf.getWeatherSetup(std::min((uint) (floorf(wv) + 1), wf.getNumWeatherSetups() - 1)); - std::string name1 = ws ? NLMISC::CStringMapper::unmap(ws->SetupName) : "???"; - TextContext->printfAt(1.f, line, "Weather value : %.02f : %s -> %s", ws ? wv : 0.f, name0.c_str(), name1.c_str()); - line += lineStep; - } - else - { - TextContext->printfAt(1.f, line, "Weather value : %.02f", WeatherManager.getWeatherValue() * std::max(ContinentMngr.cur()->WeatherFunction[CurrSeason].getNumWeatherSetups() - 1, 0u)); - line += lineStep; - TextContext->printfAt(1.f, line, "TEST WEATHER FUNCTION"); - line += lineStep; - } - // season - TextContext->printfAt(1.f, line, "Season : %s", EGSPD::CSeason::toString(CurrSeason).c_str()); - line += lineStep; - } - } - - // fog dist - if (ContinentMngr.cur()) - { - TextContext->printfAt(1.f, line, "Continent fog min near = %.1f, max far = %.1f", ContinentMngr.cur()->FogStart, ContinentMngr.cur()->FogEnd); - line += lineStep; - CFogState tmpFog; - ContinentMngr.getFogState(MainFog, LightCycleManager.getLightLevel(), LightCycleManager.getLightDesc().DuskRatio, LightCycleManager.getState(), View.viewPos(), tmpFog); - TextContext->printfAt(1.f, line, "Continent fog curr near = %.1f, curr far = %.1f", tmpFog.FogStartDist, tmpFog.FogEndDist); - line += lineStep; - } - const CWeatherState &ws = WeatherManager.getCurrWeatherState(); - TextContext->printfAt(1.f, line, "Weather fog near = %.1f, far = %.1f", ws.FogNear[MainFog], ws.FogFar[MainFog]); - line += lineStep; - TextContext->printfAt(1.f, line, "Final fog near = %.1f, far = %.1f", MainFogState.FogStartDist, MainFogState.FogEndDist); - line += lineStep; - float left, right, bottom, top, znear, zfar; - Scene->getCam().getFrustum(left, right, bottom, top, znear, zfar); - TextContext->printfAt(1.f, line, "Clip near = %.1f, far = %.1f", znear, zfar); - line += lineStep; - - // Connection states - TextContext->printfAt(1.f, line, "State : %s", NetMngr.getConnectionStateCStr() ); - line += lineStep; - -// UGlobalPosition globalPos; -// UserEntity->getPrimitive()->getGlobalPosition(globalPos, dynamicWI); -// uint32 material = GR->getMaterial( globalPos ); -// TextContext->printfAt(0.5f,0.5f,"Material : %d Gpos=(inst=%d,surf=%d,x=%.2f,y=%.2f",material, globalPos.InstanceId, globalPos.LocalPosition.Surface, globalPos.LocalPosition.Estimation.x, globalPos.LocalPosition.Estimation.y); - - // No more shadow when displaying a text. - TextContext->setShaded(false); -}// displayDebug // - -//----------------------------------------------- -// Macro to Display a Text -//----------------------------------------------- -#define DISP_TEXT(x, text) \ - /* Display the text at the right place */ \ - TextContext->printfAt(x, line, text); \ - /* Change the line */ \ - line += lineStep; \ - -//--------------------------------------------------- -// displayHelp : -// Display an Help. -//--------------------------------------------------- -void displayHelp() -{ - float line = 1.f; - float lineStep = -ClientCfg.HelpLineStep; - - // Create a shadow when displaying a text. - TextContext->setShaded(true); - // Set the font size. - TextContext->setFontSize(ClientCfg.HelpFontSize); - // Set the text color - TextContext->setColor(ClientCfg.HelpFontColor); - - - line = 1.f; - TextContext->setHotSpot(UTextContext::TopLeft); - DISP_TEXT(0.0f, "SHIFT + F1 : This Menu") - DISP_TEXT(0.0f, "SHIFT + F2 : Display Debug Infos") - DISP_TEXT(0.0f, "SHIFT + F3 : Wire mode"); - DISP_TEXT(0.0f, "SHIFT + F4 : Do not Render the Scene"); - DISP_TEXT(0.0f, "SHIFT + F5 : Toogle Display OSD interfaces"); -// DISP_TEXT(0.0f, "SHIFT + F6 : Not used"); - DISP_TEXT(0.0f, "SHIFT + F7 : Compass Mode (User/Camera)"); - DISP_TEXT(0.0f, "SHIFT + F8 : Camera Mode (INSERT to change your position)"); - DISP_TEXT(0.0f, "SHIFT + F9 : Free Mouse"); - DISP_TEXT(0.0f, "SHIFT + F10 : Take a Screen Shot (+CTRL) for jpg"); -// DISP_TEXT(0.0f, "SHIFT + F11 : Test"); - DISP_TEXT(0.0f, "SHIFT + ESCAPE : Quit"); - DISP_TEXT(0.0f, "SHIFT + C : First/Third Person View"); - - line = 1.f; - TextContext->setHotSpot(UTextContext::TopRight); - DISP_TEXT(1.0f, "UP : FORWARD"); - DISP_TEXT(1.0f, "DOWN : BACKWARD"); - DISP_TEXT(1.0f, "LEFT : ROTATE LEFT"); - DISP_TEXT(1.0f, "RIGHT : ROTATE RIGHT"); - DISP_TEXT(1.0f, "CTRL + LEFT : STRAFE LEFT"); - DISP_TEXT(1.0f, "CTRL + RIGHT : STRAFE RIGHT"); - DISP_TEXT(1.0f, "END : Auto Walk"); - DISP_TEXT(1.0f, "DELETE : Walk/Run"); - DISP_TEXT(1.0f, "PG UP : Look Up"); - DISP_TEXT(1.0f, "PG DOWN : Look Down"); -// DISP_TEXT(1.0f, "CTRL + I : Inventory"); -// DISP_TEXT(1.0f, "CTRL + C : Spells composition interface"); -// DISP_TEXT(1.0f, "CTRL + S : Memorized Spells interface"); - DISP_TEXT(1.0f, "CTRL + B : Show/Hide PACS Borders"); - DISP_TEXT(1.0f, "CTRL + P : Player target himself"); - DISP_TEXT(1.0f, "CTRL + D : Unselect target"); - DISP_TEXT(1.0f, "CTRL + TAB : Next Chat Mode (say/shout"); - DISP_TEXT(1.0f, "CTRL + R : Reload Client.cfg File"); -// DISP_TEXT(1.0f, "CTRL + N : Toggle Night / Day lighting"); - DISP_TEXT(1.0f, "CTRL + F2 : Profile on / off"); - DISP_TEXT(1.0f, "CTRL + F3 : Movie Shooter record / stop"); - DISP_TEXT(1.0f, "CTRL + F4 : Movie Shooter replay"); - DISP_TEXT(1.0f, "CTRL + F5 : Movie Shooter save"); -#ifndef NL_USE_DEFAULT_MEMORY_MANAGER - DISP_TEXT(1.0f, "CTRL + F6 : Save memory stat report"); -#endif // NL_USE_DEFAULT_MEMORY_MANAGER - DISP_TEXT(1.0f, "CTRL + F7 : Show / hide prim file"); - DISP_TEXT(1.0f, "CTRL + F8 : Change prim file UP"); - DISP_TEXT(1.0f, "CTRL + F9 : Change prim file DOWN"); - - // No more shadow when displaying a text. - TextContext->setShaded(false); -}// displayHelp // - - //--------------------------------------------------- // Just Display some text with ... anim at some place. //--------------------------------------------------- diff --git a/code/ryzom/client/src/main_loop.h b/code/ryzom/client/src/main_loop.h index c8cd0af5a..21f64d37e 100644 --- a/code/ryzom/client/src/main_loop.h +++ b/code/ryzom/client/src/main_loop.h @@ -29,9 +29,13 @@ const uint NUM_MISSION_OPTIONS = 8; bool mainLoop(); // render all -void renderAll(bool forceFullDetail = false); +void renderScene(); +void renderScene(bool forceFullDetail, bool bloom); void setDefaultChatWindow(CChatWindow *defaultChatWindow); +// Commit sky scene camera for rendering +void commitCamera(); + void updateDayNightCycleHour(); diff --git a/code/ryzom/client/src/main_loop_debug.cpp b/code/ryzom/client/src/main_loop_debug.cpp new file mode 100644 index 000000000..dbcb47b96 --- /dev/null +++ b/code/ryzom/client/src/main_loop_debug.cpp @@ -0,0 +1,774 @@ +// Ryzom - MMORPG Framework +// 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 . + +#include +#include "main_loop_debug.h" + +#include +#include + +#include "game_share/ryzom_version.h" + +#include "global.h" +#include "client_cfg.h" +#include "user_entity.h" +#include "debug_client.h" +#include "entities.h" +#include "motion/user_controls.h" +#include "pacs_client.h" +#include "sound_manager.h" +#include "view.h" +#include "prim_file.h" +#include "weather.h" +#include "light_cycle_manager.h" +#include "net_manager.h" +#include "ping.h" +#include "world_database_manager.h" +#include "continent_manager.h" +#include "client_sheets/weather_function_params_sheet.h" +#include "weather_manager_client.h" +#include "fog_map.h" +#include "misc.h" +#include "interface_v3/interface_manager.h" + +using namespace NLMISC; +using namespace NL3D; +using namespace NLGUI; + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +extern std::set LodCharactersNotFound; +extern uint32 NbDatabaseChanges; +extern CFogState MainFogState; +extern CPing Ping; +extern bool Filter3D[RYZOM_MAX_FILTER_3D]; + +//namespace /* anonymous */ { + +NLMISC::CValueSmoother smoothFPS; +NLMISC::CValueSmoother moreSmoothFPS(64); + +//} /* anonymous namespace */ + +//--------------------------------------------------- +// displayDebug : +// Display some debug infos. +//--------------------------------------------------- +void displayDebug() +{ + float lineStep = ClientCfg.DebugLineStep; + float line; + + // Initialize Pen // + //----------------// + // Create a shadow when displaying a text. + TextContext->setShaded(true); + // Set the font size. + TextContext->setFontSize(ClientCfg.DebugFontSize); + // Set the text color + TextContext->setColor(ClientCfg.DebugFontColor); + + // TOP LEFT // + //----------// + TextContext->setHotSpot(UTextContext::TopLeft); + line = 0.9f; + // FPS and Ms per frame + { + // smooth across frames. + double deltaTime = smoothFPS.getSmoothValue (); + // FPS and Ms per frame + if(deltaTime != 0.f) + TextContext->printfAt(0.f, line,"%.1f fps", 1.f/deltaTime); + else + TextContext->printfAt(0.f, line,"%.1f fps", 0.f); + TextContext->printfAt(0.1f, line, "%d ms", (uint)(deltaTime*1000)); + } + line -= lineStep; + line -= lineStep; + + // USER + // Front + TextContext->printfAt(0.0f, line, " %f (%f,%f,%f) front", atan2(UserEntity->front().y, UserEntity->front().x), UserEntity->front().x, UserEntity->front().y, UserEntity->front().z); + line -= lineStep; + // Dir + TextContext->printfAt(0.0f, line, " %f (%f,%f,%f) dir", atan2(UserEntity->dir().y, UserEntity->dir().x), UserEntity->dir().x, UserEntity->dir().y, UserEntity->dir().z); + line -= lineStep; + // NB Stage + TextContext->printfAt(0.0f, line, " NB Stage: %d", UserEntity->nbStage()); + line -= lineStep; + // NB Animation FXs still remaining in the remove list. + TextContext->printfAt(0.0f, line, " NB FXs to remove: %d", UserEntity->nbAnimFXToRemove()); + line -= lineStep; + // Mode. + TextContext->printfAt(0.0f, line, " Mode: %d (%s)", (sint)UserEntity->mode(), MBEHAV::modeToString(UserEntity->mode()).c_str()); + line -= lineStep; + // Behaviour. + TextContext->printfAt(0.0f, line, " Behaviour: %d (%s)", (sint)UserEntity->behaviour(), MBEHAV::behaviourToString(UserEntity->behaviour()).c_str()); + line -= lineStep; + // Display the target mount. + TextContext->printfAt(0.0f, line, " Mount: %d", UserEntity->mount()); + line -= lineStep; + // Display the target rider. + TextContext->printfAt(0.0f, line, " Rider: %d", UserEntity->rider()); + line -= lineStep; + // Display the current animation name. + TextContext->printfAt(0.0f, line, " Current Animation Name: %s", UserEntity->currentAnimationName().c_str()); + line -= lineStep; + // Display the current move animation set name. + TextContext->printfAt(0.0f, line, " Current AnimationSet Name (MOVE): %s", UserEntity->currentAnimationSetName(MOVE).c_str()); + line -= lineStep; + // Display Missing Animations + if(::CAnimation::MissingAnim.empty() == false) + { + TextContext->printfAt(0.0f, line, " '%u' Missing Animations, 1st: '%s'", ::CAnimation::MissingAnim.size(), (*(::CAnimation::MissingAnim.begin())).c_str()); + line -= lineStep; + } + // Display Missing LoD + if(LodCharactersNotFound.empty() == false) + { + TextContext->printfAt(0.0f, line, " '%u' Missing LoD, 1st: '%s'", LodCharactersNotFound.size(), (*(LodCharactersNotFound.begin())).c_str()); + line -= lineStep; + } + + // Watched Entity + line -= lineStep; + // Now Displaying the selection. + TextContext->printfAt(0.0f, line, "--*** Watched entity ***--"); + line -= lineStep; + // Display information about the debug entity slot. + if(WatchedEntitySlot != CLFECOMMON::INVALID_SLOT) + { + // Get a pointer on the target. + CEntityCL *watchedEntity = EntitiesMngr.entity(WatchedEntitySlot); + if(watchedEntity) + { + // Display Debug Information about the Selection. + watchedEntity->displayDebug(0.0f, line, -lineStep); + + // Distance of the target + CVectorD diffvector = UserEntity->pos() - watchedEntity->pos(); + TextContext->printfAt(0.0f, line, " Distance: %10.2f (Manhattan: %.2f)", diffvector.norm(), fabs(diffvector.x) + fabs(diffvector.y) ); + line -= lineStep; + } + // Target not allocated + else + { + TextContext->printfAt(0.0f, line, "Not allocated (%d)", WatchedEntitySlot); + line -= lineStep; + } + } + // No Target + else + { + TextContext->printfAt(0.0f, line, "None"); + line -= lineStep; + } + + /* Ca rame grave ! + + uint nMem = NLMEMORY::GetAllocatedMemory(); + line -= lineStep; + TextContext->printfAt(0.0f, line, "Mem Used: %d",nMem);*/ + + // 3D Filters information: +#ifdef _PROFILE_ON_ + line-= lineStep; + TextContext->printfAt(0.0f, line, "3D Filters:"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "MeshNoVP: %s", Filter3D[FilterMeshNoVP]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "MeshVP: %s", Filter3D[FilterMeshVP]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "FXs: %s", Filter3D[FilterFXs]?"Ok":"NOT RENDERED!"); + line-= lineStep; + if (Landscape) + { + TextContext->printfAt(0.0f, line, "Landscape: %s", Filter3D[FilterLandscape]?"Ok":"NOT RENDERED!"); + line-= lineStep; + } + else + { + TextContext->printfAt(0.0f, line, "Landscape not enabled"); + } + TextContext->printfAt(0.0f, line, "Vegetable: %s", Filter3D[FilterVegetable]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "Skeleton: %s", Filter3D[FilterSkeleton]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "Water: %s", Filter3D[FilterWater]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "Cloud: %s", Filter3D[FilterCloud]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "CoarseMesh: %s", Filter3D[FilterCoarseMesh]?"Ok":"NOT RENDERED!"); + line-= lineStep; + TextContext->printfAt(0.0f, line, "Sky: %s", Filter3D[FilterSky]?"Ok":"NOT RENDERED!"); + line-= lineStep; + // Materials Infos + TextContext->printfAt(0.0f, line, "SetupedMatrix: %d", Driver->profileSetupedModelMatrix() ); + line-= lineStep; + TextContext->printfAt(0.0f, line, "SetupedMaterials: %d", Driver->profileSetupedMaterials() ); + line-= lineStep; + // Display camera cluster system + TextContext->printfAt(0.0f, line, "ClusterSystem: %p", MainCam.getClusterSystem() ); + line-= 2 * lineStep; + // Lua stuffs + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + TextContext->printfAt(0.0f, line, "Lua mem (kb) : %d / %d", CLuaManager::getInstance().getLuaState()->getGCCount(), CLuaManager::getInstance().getLuaState()->getGCThreshold()); + line-= lineStep; + TextContext->printfAt(0.0f, line, "Lua stack size = %d", CLuaManager::getInstance().getLuaState()->getTop()); + line-= lineStep; + +#endif + + // TOP LEFT // + //-----------// + TextContext->setHotSpot(UTextContext::TopLeft); + line = 1.f; + string str; +#if FINAL_VERSION + str = "FV"; +#else + str = "DEV"; +#endif + if(ClientCfg.ExtendedCommands) + str += "_E"; + str += " "RYZOM_VERSION; + TextContext->printfAt(0.f, line, "Version %s", str.c_str()); + + // TOP MIDDLE // + //------------// + TextContext->setHotSpot(UTextContext::MiddleTop); + line = 1.f; + // Motion Mode + TextContext->printfAt(0.5f, line, "%s", UserControls.modeStr().c_str()); + line -= lineStep; + + // TOP RIGHT // + //-----------// + TextContext->setHotSpot(UTextContext::TopRight); + line = 1.f; + //// 3D Infos + // Video mem allocated. + TextContext->printfAt(1.f, line, "Video mem. : %f", Driver->profileAllocatedTextureMemory()/(1024.f*1024.f)); + line -= lineStep; + // Video mem used since last swapBuffers(). + TextContext->printfAt(1.f, line, "Video mem. since last swap buffer: %f", Driver->getUsedTextureMemory()/(1024.f*1024.f)); + line -= lineStep; + // Get the last face count asked from the main scene before reduction. + TextContext->printfAt(1.f, line, "Nb Skin Face Asked: %f", Scene->getGroupNbFaceAsked("Skin")); + line -= lineStep; + TextContext->printfAt(1.f, line, "Nb Fx Face Asked: %f", Scene->getGroupNbFaceAsked("Fx")); + line -= lineStep; + // All Triangles In + CPrimitiveProfile pIn; + CPrimitiveProfile pOut; + Driver->profileRenderedPrimitives(pIn, pOut); + TextContext->printfAt(1.f, line, "Tri In : %d", pIn.NTriangles+2*pIn.NQuads); + line -= lineStep; + // All Triangles Out + TextContext->printfAt(1.f, line, "Tri Out : %d", pOut.NTriangles+2*pIn.NQuads); + line -= lineStep; + // Current Cluster + string strPos; + // Check there is a PACS Primitive before using it. + if(UserEntity->getPrimitive() && GR) + { + UGlobalPosition gPos; + UserEntity->getPrimitive()->getGlobalPosition(gPos, dynamicWI); + string strPos = GR->getIdentifier(gPos); + } + else + strPos = "No Primitive"; + TextContext->printfAt(1.f, line, "Cluster : %s", strPos.c_str()); + line -= lineStep; + //// SOUND Infos + line -= lineStep; + if(SoundMngr) + { + TextContext->printfAt(1.f, line, "Sound source instance: %u", SoundMngr->getSourcesInstanceCount()); + line -= lineStep; + TextContext->printfAt(1.f, line, "Logical playing SoundSource: %u", SoundMngr->getMixer()->getPlayingSourcesCount ()); + line -= lineStep; + TextContext->printfAt(1.f, line, "Audio tracks: %u/%u", SoundMngr->getMixer()->getUsedTracksCount(), SoundMngr->getMixer()->getPolyphony()); + line -= lineStep; + if (SoundMngr->getMixer()->getMutedPlayingSourcesCount() > 0) + { + TextContext->printfAt(1.f, line, "Source muted: %u !", SoundMngr->getMixer()->getMutedPlayingSourcesCount()); + line -= lineStep; + } + TextContext->printfAt(1.f, line, "Samples in memory: %g MB", SoundMngr->getLoadingSamplesSize() / (1024.0f*1024.0f)); + line -= lineStep; + + } + + // BOTTOM RIGHT // + //--------------// + TextContext->setHotSpot(UTextContext::BottomRight); + line = 0.f; + //// POSITION + CVector postmp = View.viewPos(); + // Pos + TextContext->printfAt(1.f, line, "Position : %d %d %d",(int)postmp.x,(int)postmp.y,(int)postmp.z); + line += lineStep; + // Body Heading + TextContext->printfAt(1.f, line, "Front : %.2f %.2f %.2f", UserEntity->front().x, UserEntity->front().y, UserEntity->front().z); + line += lineStep; + // Speed + TextContext->printfAt(1.f, line, "Speed : %.2f", (float) UserEntity->speed()); + line += lineStep; + // Zone + if (!ClientCfg.Light) + { + if (Landscape) + { + TextContext->printfAt(1.f, line, "Zone: %s", Landscape->getZoneName(postmp).c_str()); + line += lineStep; + } + } + // Prim File + string primFile = PrimFiles.getCurrentPrimitive (); + if (!primFile.empty ()) + { + TextContext->printfAt(1.f, line, "Prim File: %s", primFile.c_str ()); + line += lineStep; + } + + //// CONNECTION + line += lineStep; + // Ryzom Day. + TextContext->printfAt(1.f, line, "Ryzom Day : %d", RT.getRyzomDay()); + line += lineStep; + // hour in the game + float dayNightCycleHour = (float)RT.getRyzomTime(); + TextContext->printfAt(1.f, line, "Ryzom Time : %2u:%02u", int(dayNightCycleHour), int((dayNightCycleHour-int(dayNightCycleHour))*60.0f)); + line += lineStep; + // light hour in the game, used to display te day/night + TextContext->printfAt(1.f, line, "Ryzom Light Time : %2u:%02u (%s)", int(DayNightCycleHour), int((DayNightCycleHour-int(DayNightCycleHour))*60.0f), LightCycleManager.getStateString().c_str()); + line += lineStep; + // Server GameCycle + TextContext->printfAt(1.f, line, "Server GameCycle : %u", (uint)NetMngr.getCurrentServerTick()); + line += lineStep; + // Current GameCycle + TextContext->printfAt(1.f, line, "Current GameCycle : %u", (uint)NetMngr.getCurrentClientTick()); + line += lineStep; + // Current GameCycle + TextContext->printfAt(1.f, line, "Ms per Cycle : %d", NetMngr.getMsPerTick()); + line += lineStep; + // Packet Loss + TextContext->printfAt(1.f, line, "Packet Loss : %.1f %%", NetMngr.getMeanPacketLoss()*100.0f); + line += lineStep; + // Packet Loss + TextContext->printfAt(1.f, line, "Packets Lost : %u", NetMngr.getTotalLostPackets()); + line += lineStep; + // Mean Upload + TextContext->printfAt(1.f, line, "Mean Upld : %.3f kbps", NetMngr.getMeanUpload()); + line += lineStep; + // Mean Download + TextContext->printfAt(1.f, line, "Mean Dnld : %.3f kbps", NetMngr.getMeanDownload()); + line += lineStep; + + // Mean Download + TextContext->printfAt(1.f, line, "Nb in Vision : %d(%d,%d,%d)", + EntitiesMngr.nbEntitiesAllocated(), + EntitiesMngr.nbUser(), + EntitiesMngr.nbPlayer(), + EntitiesMngr.nbChar()); + line += lineStep; + + // Number of database changes + TextContext->printfAt(1.f, line, "DB Changes : %u", NbDatabaseChanges ); + line += lineStep; + + // Ping + TextContext->printfAt(1.f, line, "DB Ping : %u ms", Ping.getValue()); + line += lineStep; + + + + + + // Manual weather setup + { + if(ContinentMngr.cur()) // Only usable if there is a continent loaded. + { + if (!ForceTrueWeatherValue) + { + const CWeatherFunction &wf = ContinentMngr.cur()->WeatherFunction[CurrSeason]; + float wv; + if (ClientCfg.ManualWeatherSetup) + { + wv = std::max(wf.getNumWeatherSetups() - 1, 0u) * ManualWeatherValue; + } + else + { + wv = std::max(wf.getNumWeatherSetups() - 1, 0u) * ::getBlendedWeather(RT.getRyzomDay(), RT.getRyzomTime(), *WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction); + } + const CWeatherSetup *ws = wf.getWeatherSetup((uint) floorf(wv)); + std::string name0 = ws ? NLMISC::CStringMapper::unmap(ws->SetupName) : "???"; + ws = wf.getWeatherSetup(std::min((uint) (floorf(wv) + 1), wf.getNumWeatherSetups() - 1)); + std::string name1 = ws ? NLMISC::CStringMapper::unmap(ws->SetupName) : "???"; + TextContext->printfAt(1.f, line, "Weather value : %.02f : %s -> %s", ws ? wv : 0.f, name0.c_str(), name1.c_str()); + line += lineStep; + } + else + { + TextContext->printfAt(1.f, line, "Weather value : %.02f", WeatherManager.getWeatherValue() * std::max(ContinentMngr.cur()->WeatherFunction[CurrSeason].getNumWeatherSetups() - 1, 0u)); + line += lineStep; + TextContext->printfAt(1.f, line, "TEST WEATHER FUNCTION"); + line += lineStep; + } + // season + TextContext->printfAt(1.f, line, "Season : %s", EGSPD::CSeason::toString(CurrSeason).c_str()); + line += lineStep; + } + } + + // fog dist + if (ContinentMngr.cur()) + { + TextContext->printfAt(1.f, line, "Continent fog min near = %.1f, max far = %.1f", ContinentMngr.cur()->FogStart, ContinentMngr.cur()->FogEnd); + line += lineStep; + CFogState tmpFog; + ContinentMngr.getFogState(MainFog, LightCycleManager.getLightLevel(), LightCycleManager.getLightDesc().DuskRatio, LightCycleManager.getState(), View.viewPos(), tmpFog); + TextContext->printfAt(1.f, line, "Continent fog curr near = %.1f, curr far = %.1f", tmpFog.FogStartDist, tmpFog.FogEndDist); + line += lineStep; + } + const CWeatherState &ws = WeatherManager.getCurrWeatherState(); + TextContext->printfAt(1.f, line, "Weather fog near = %.1f, far = %.1f", ws.FogNear[MainFog], ws.FogFar[MainFog]); + line += lineStep; + TextContext->printfAt(1.f, line, "Final fog near = %.1f, far = %.1f", MainFogState.FogStartDist, MainFogState.FogEndDist); + line += lineStep; + float left, right, bottom, top, znear, zfar; + Scene->getCam().getFrustum(left, right, bottom, top, znear, zfar); + TextContext->printfAt(1.f, line, "Clip near = %.1f, far = %.1f", znear, zfar); + line += lineStep; + + // Connection states + TextContext->printfAt(1.f, line, "State : %s", NetMngr.getConnectionStateCStr() ); + line += lineStep; + +// UGlobalPosition globalPos; +// UserEntity->getPrimitive()->getGlobalPosition(globalPos, dynamicWI); +// uint32 material = GR->getMaterial( globalPos ); +// TextContext->printfAt(0.5f,0.5f,"Material : %d Gpos=(inst=%d,surf=%d,x=%.2f,y=%.2f",material, globalPos.InstanceId, globalPos.LocalPosition.Surface, globalPos.LocalPosition.Estimation.x, globalPos.LocalPosition.Estimation.y); + + // No more shadow when displaying a text. + TextContext->setShaded(false); +}// displayDebug // + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +//--------------------------------------------------- +// displayDebug : +// Display some debug infos. +//--------------------------------------------------- +void displayDebugFps() +{ + float lineStep = ClientCfg.DebugLineStep; + float line; + + // Initialize Pen // + //----------------// + // Create a shadow when displaying a text. + TextContext->setShaded(true); + // Set the font size. + TextContext->setFontSize(ClientCfg.DebugFontSize); + // Set the text color + TextContext->setColor(ClientCfg.DebugFontColor); + + // TOP LEFT // + //----------// + TextContext->setHotSpot(UTextContext::TopLeft); + line = 0.9f; + // Ms per frame + { + float spf = smoothFPS.getSmoothValue (); + // Ms per frame + TextContext->printfAt(0.1f, line, "FPS %.1f ms - %.1f fps", spf*1000, 1.f/spf); + line-= lineStep; + // More Smoothed Ms per frame + spf = moreSmoothFPS.getSmoothValue (); + TextContext->printfAt(0.1f, line, "Smoothed FPS %.1f ms - %.1f fps", spf*1000, 1.f/spf); + line-= lineStep; + } +} + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +static NLMISC::CRefPtr HighlightedDebugUI; + +// displayDebug : +// Display information about ui elements that are under the mouse +//--------------------------------------------------- +void displayDebugUIUnderMouse() +{ + float lineStep = ClientCfg.DebugLineStep; + float line; + + // Initialize Pen // + //----------------// + // Create a shadow when displaying a text. + TextContext->setShaded(true); + // Set the font size. + TextContext->setFontSize(ClientCfg.DebugFontSize); + + + + // TOP LEFT // + //----------// + TextContext->setHotSpot(UTextContext::TopLeft); + line = 0.9f; + + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + // for now only accessible with R2ED + if (ClientCfg.R2EDEnabled) + { + TextContext->setColor(CRGBA::Cyan); + TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+A) to cycle prev"); + line-= lineStep; + TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+Q) to cycle next"); + line-= lineStep; + TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+W) to inspect element"); + line-= 2 * lineStep; + } + // + const std::vector &rICL = CWidgetManager::getInstance()->getCtrlsUnderPointer (); + const std::vector &rIGL = CWidgetManager::getInstance()->getGroupsUnderPointer (); + // If previous highlighted element is found in the list, then keep it, else reset to first element + if (std::find(rICL.begin(), rICL.end(), HighlightedDebugUI) == rICL.end() && + std::find(rIGL.begin(), rIGL.end(), HighlightedDebugUI) == rIGL.end()) + { + if (!rICL.empty()) + { + HighlightedDebugUI = rICL[0]; + } + else + if (!rIGL.empty()) + { + HighlightedDebugUI = rIGL[0]; + } + else + { + HighlightedDebugUI = NULL; + } + } + // + TextContext->setColor(CRGBA::Green); + TextContext->printfAt(0.1f, line, "Controls under cursor "); + line -= lineStep * 1.4f; + TextContext->printfAt(0.1f, line, "----------------------"); + line -= lineStep; + for(uint k = 0; k < rICL.size(); ++k) + { + if (rICL[k]) + { + TextContext->setColor(rICL[k] != HighlightedDebugUI ? ClientCfg.DebugFontColor : CRGBA::Red); + TextContext->printfAt(0.1f, line, "id = %s, address = 0x%p, parent = 0x%p", rICL[k]->getId().c_str(), rICL[k], rICL[k]->getParent()); + } + else + { + TextContext->setColor(CRGBA::Blue); + TextContext->printfAt(0.1f, line, " control found !!!"); + } + line-= lineStep; + } + // + TextContext->setColor(CRGBA::Green); + TextContext->printfAt(0.1f, line, "Groups under cursor "); + line -= lineStep * 1.4f; + TextContext->printfAt(0.1f, line, "----------------------"); + line-= lineStep; + for(uint k = 0; k < rIGL.size(); ++k) + { + if (rIGL[k]) + { + TextContext->setColor(rIGL[k] != HighlightedDebugUI ? ClientCfg.DebugFontColor : CRGBA::Red); + TextContext->printfAt(0.1f, line, "id = %s, address = 0x%p, parent = 0x%p", rIGL[k]->getId().c_str(), rIGL[k], rIGL[k]->getParent()); + } + else + { + TextContext->setColor(CRGBA::Blue); + TextContext->printfAt(0.1f, line, " group found !!!"); + } + line-= lineStep; + } +} + +// get all element under the mouse in a single vector +static void getElementsUnderMouse(std::vector &ielem) +{ + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + const std::vector &rICL = CWidgetManager::getInstance()->getCtrlsUnderPointer(); + const std::vector &rIGL = CWidgetManager::getInstance()->getGroupsUnderPointer(); + ielem.clear(); + ielem.insert(ielem.end(), rICL.begin(), rICL.end()); + ielem.insert(ielem.end(), rIGL.begin(), rIGL.end()); +} + +class CHandlerDebugUiPrevElementUnderMouse : public IActionHandler +{ + virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) + { + std::vector ielem; + getElementsUnderMouse(ielem); + for(uint k = 0; k < ielem.size(); ++k) + { + if (HighlightedDebugUI == ielem[k]) + { + HighlightedDebugUI = ielem[k == 0 ? ielem.size() - 1 : k - 1]; + return; + } + } + } +}; +REGISTER_ACTION_HANDLER( CHandlerDebugUiPrevElementUnderMouse, "debug_ui_prev_element_under_mouse"); + +class CHandlerDebugUiNextElementUnderMouse : public IActionHandler +{ + virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) + { + std::vector ielem; + getElementsUnderMouse(ielem); + for(uint k = 0; k < ielem.size(); ++k) + { + if (HighlightedDebugUI == ielem[k]) + { + HighlightedDebugUI = ielem[(k + 1) % ielem.size()]; + return; + } + } + } +}; +REGISTER_ACTION_HANDLER( CHandlerDebugUiNextElementUnderMouse, "debug_ui_next_element_under_mouse"); + +class CHandlerDebugUiDumpElementUnderMouse : public IActionHandler +{ + virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) + { + if (HighlightedDebugUI == NULL) return; + CLuaState *lua = CLuaManager::getInstance().getLuaState(); + if (!lua) return; + CLuaStackRestorer lsr(lua, 0); + CLuaIHM::pushUIOnStack(*lua, HighlightedDebugUI); + lua->pushGlobalTable(); + CLuaObject env(*lua); + env["inspect"].callNoThrow(1, 0); + } +}; +REGISTER_ACTION_HANDLER( CHandlerDebugUiDumpElementUnderMouse, "debug_ui_inspect_element_under_mouse"); + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +//----------------------------------------------- +// Macro to Display a Text +//----------------------------------------------- +#define DISP_TEXT(x, text) \ + /* Display the text at the right place */ \ + TextContext->printfAt(x, line, text); \ + /* Change the line */ \ + line += lineStep; \ + +//--------------------------------------------------- +// displayHelp : +// Display an Help. +//--------------------------------------------------- +void displayHelp() +{ + float line = 1.f; + float lineStep = -ClientCfg.HelpLineStep; + + // Create a shadow when displaying a text. + TextContext->setShaded(true); + // Set the font size. + TextContext->setFontSize(ClientCfg.HelpFontSize); + // Set the text color + TextContext->setColor(ClientCfg.HelpFontColor); + + + line = 1.f; + TextContext->setHotSpot(UTextContext::TopLeft); + DISP_TEXT(0.0f, "SHIFT + F1 : This Menu") + DISP_TEXT(0.0f, "SHIFT + F2 : Display Debug Infos") + DISP_TEXT(0.0f, "SHIFT + F3 : Wire mode"); + DISP_TEXT(0.0f, "SHIFT + F4 : Do not Render the Scene"); + DISP_TEXT(0.0f, "SHIFT + F5 : Toogle Display OSD interfaces"); +// DISP_TEXT(0.0f, "SHIFT + F6 : Not used"); + DISP_TEXT(0.0f, "SHIFT + F7 : Compass Mode (User/Camera)"); + DISP_TEXT(0.0f, "SHIFT + F8 : Camera Mode (INSERT to change your position)"); + DISP_TEXT(0.0f, "SHIFT + F9 : Free Mouse"); + DISP_TEXT(0.0f, "SHIFT + F10 : Take a Screen Shot (+CTRL) for jpg"); +// DISP_TEXT(0.0f, "SHIFT + F11 : Test"); + DISP_TEXT(0.0f, "SHIFT + ESCAPE : Quit"); + DISP_TEXT(0.0f, "SHIFT + C : First/Third Person View"); + + line = 1.f; + TextContext->setHotSpot(UTextContext::TopRight); + DISP_TEXT(1.0f, "UP : FORWARD"); + DISP_TEXT(1.0f, "DOWN : BACKWARD"); + DISP_TEXT(1.0f, "LEFT : ROTATE LEFT"); + DISP_TEXT(1.0f, "RIGHT : ROTATE RIGHT"); + DISP_TEXT(1.0f, "CTRL + LEFT : STRAFE LEFT"); + DISP_TEXT(1.0f, "CTRL + RIGHT : STRAFE RIGHT"); + DISP_TEXT(1.0f, "END : Auto Walk"); + DISP_TEXT(1.0f, "DELETE : Walk/Run"); + DISP_TEXT(1.0f, "PG UP : Look Up"); + DISP_TEXT(1.0f, "PG DOWN : Look Down"); +// DISP_TEXT(1.0f, "CTRL + I : Inventory"); +// DISP_TEXT(1.0f, "CTRL + C : Spells composition interface"); +// DISP_TEXT(1.0f, "CTRL + S : Memorized Spells interface"); + DISP_TEXT(1.0f, "CTRL + B : Show/Hide PACS Borders"); + DISP_TEXT(1.0f, "CTRL + P : Player target himself"); + DISP_TEXT(1.0f, "CTRL + D : Unselect target"); + DISP_TEXT(1.0f, "CTRL + TAB : Next Chat Mode (say/shout"); + DISP_TEXT(1.0f, "CTRL + R : Reload Client.cfg File"); +// DISP_TEXT(1.0f, "CTRL + N : Toggle Night / Day lighting"); + DISP_TEXT(1.0f, "CTRL + F2 : Profile on / off"); + DISP_TEXT(1.0f, "CTRL + F3 : Movie Shooter record / stop"); + DISP_TEXT(1.0f, "CTRL + F4 : Movie Shooter replay"); + DISP_TEXT(1.0f, "CTRL + F5 : Movie Shooter save"); +#ifndef NL_USE_DEFAULT_MEMORY_MANAGER + DISP_TEXT(1.0f, "CTRL + F6 : Save memory stat report"); +#endif // NL_USE_DEFAULT_MEMORY_MANAGER + DISP_TEXT(1.0f, "CTRL + F7 : Show / hide prim file"); + DISP_TEXT(1.0f, "CTRL + F8 : Change prim file UP"); + DISP_TEXT(1.0f, "CTRL + F9 : Change prim file DOWN"); + + // No more shadow when displaying a text. + TextContext->setShaded(false); +}// displayHelp // + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +/* end of file */ \ No newline at end of file diff --git a/code/nel/src/3d/driver/opengl3/driver_glsl_vertex_program.cpp b/code/ryzom/client/src/main_loop_debug.h similarity index 63% rename from code/nel/src/3d/driver/opengl3/driver_glsl_vertex_program.cpp rename to code/ryzom/client/src/main_loop_debug.h index a9c0273b6..70139290e 100644 --- a/code/nel/src/3d/driver/opengl3/driver_glsl_vertex_program.cpp +++ b/code/ryzom/client/src/main_loop_debug.h @@ -1,35 +1,31 @@ -// NeL - MMORPG Framework -// 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 . - - -#include "driver_glsl_vertex_program.h" -#include "stdopengl.h" -#include "driver_opengl_extension.h" - -namespace NL3D -{ - CGLSLVertexProgram::CGLSLVertexProgram() : - CGLSLProgram() - { - type = VERTEX_PROGRAM; - } - - CGLSLVertexProgram::~CGLSLVertexProgram() - { - if( programId != 0 ) - nglDeleteProgram( programId ); - } -} \ No newline at end of file +// Ryzom - MMORPG Framework +// 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 . + +#ifndef CL_MAIN_LOOP_DEBUG_H +#define CL_MAIN_LOOP_DEBUG_H + +#include + +// Display some debug infos. +void displayDebug(); +void displayDebugFps(); +void displayDebugUIUnderMouse(); +// Display an Help. +void displayHelp(); + +#endif // CL_MAIN_LOOP_DEBUG_H + +/* end of file */ \ No newline at end of file diff --git a/code/ryzom/client/src/main_loop_temp.cpp b/code/ryzom/client/src/main_loop_temp.cpp new file mode 100644 index 000000000..0b3f24fa3 --- /dev/null +++ b/code/ryzom/client/src/main_loop_temp.cpp @@ -0,0 +1,226 @@ +// Ryzom - MMORPG Framework +// 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 . + +#include +#include "main_loop_temp.h" + +#include "global.h" + +// tempDumpValidPolys +#include +#include +#include "interface_v3/interface_manager.h" + +// tempDumpColPolys +#include +#include "r2/editor.h" +#include "user_entity.h" +#include + +using namespace NLMISC; +using namespace NL3D; + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +// TMP TMP +void tempDumpValidPolys() +{ + struct CPolyDisp : public CInterfaceElementVisitor + { + virtual void visitCtrl(CCtrlBase *ctrl) + { + CCtrlPolygon *cp = dynamic_cast(ctrl); + if (cp) + { + sint32 cornerX, cornerY; + cp->getParent()->getCorner(cornerX, cornerY, cp->getParentPosRef()); + for(sint32 y = 0; y < (sint32) Screen.getHeight(); ++y) + { + for(sint32 x = 0; x < (sint32) Screen.getWidth(); ++x) + { + if (cp->contains(CVector2f((float) (x - cornerX), (float) (y - cornerY)))) + { + ((CRGBA *) &Screen.getPixels()[0])[x + (Screen.getHeight() - 1 - y) * Screen.getWidth()] = CRGBA::Magenta; + } + } + } + } + } + CBitmap Screen; + } polyDisp; + Driver->getBuffer(polyDisp.Screen); + CInterfaceManager::getInstance()->visit(&polyDisp); + COFile output("poly.tga"); + polyDisp.Screen.writeTGA(output); +} + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +// TMP TMP +static void viewportToScissor(const CViewport &vp, CScissor &scissor) +{ + scissor.X = vp.getX(); + scissor.Y = vp.getY(); + scissor.Width = vp.getWidth(); + scissor.Height = vp.getHeight(); +} + +// TMP TMP +void tempDumpColPolys() +{ + CPackedWorld *pw = R2::getEditor().getIslandCollision().getPackedIsland(); + if (pw) + { + static CMaterial material; + static CMaterial wiredMaterial; + static CMaterial texturedMaterial; + static CVertexBuffer vb; + static bool initDone = false; + if (!initDone) + { + vb.setVertexFormat(CVertexBuffer::PositionFlag); + vb.setPreferredMemory(CVertexBuffer::AGPVolatile, false); + material.initUnlit(); + material.setDoubleSided(true); + material.setZFunc(CMaterial::lessequal); + wiredMaterial.initUnlit(); + wiredMaterial.setDoubleSided(true); + wiredMaterial.setZFunc(CMaterial::lessequal); + wiredMaterial.setColor(CRGBA(255, 255, 255, 250)); + wiredMaterial.texEnvOpAlpha(0, CMaterial::Replace); + wiredMaterial.texEnvArg0Alpha(0, CMaterial::Diffuse, CMaterial::SrcAlpha); + wiredMaterial.setBlend(true); + wiredMaterial.setBlendFunc(CMaterial::srcalpha, CMaterial::invsrcalpha); + texturedMaterial.initUnlit(); + texturedMaterial.setDoubleSided(true); + texturedMaterial.setZFunc(CMaterial::lessequal); + initDone = true; + } + // just add a projected texture + R2::getEditor().getIslandCollision().loadEntryPoints(); + R2::CScenarioEntryPoints &sep = R2::CScenarioEntryPoints::getInstance(); + CVectorD playerPos = UserEntity->pos(); + R2::CScenarioEntryPoints::CCompleteIsland *island = sep.getCompleteIslandFromCoords(CVector2f((float) playerPos.x, (float) playerPos.y)); + static CSString currIsland; + if (island && island->Island != currIsland) + { + currIsland = island->Island; + CTextureFile *newTex = new CTextureFile(currIsland + "_sp.tga"); + newTex->setWrapS(ITexture::Clamp); + newTex->setWrapT(ITexture::Clamp); + texturedMaterial.setTexture(0, newTex); + texturedMaterial.texEnvOpRGB(0, CMaterial::Replace); + texturedMaterial.texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor); + texturedMaterial.setTexCoordGen(0, true); + texturedMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace); + CMatrix mat; + CVector scale((float) (island->XMax - island->XMin), + (float) (island->YMax - island->YMin), 0.f); + scale.x = 1.f / favoid0(scale.x); + scale.y = 1.f / favoid0(scale.y); + scale.z = 0.f; + mat.setScale(scale); + mat.setPos(CVector(- island->XMin * scale.x, - island->YMin * scale.y, 0.f)); + // + CMatrix uvScaleMat; + // + uint texWidth = (uint) (island->XMax - island->XMin); + uint texHeight = (uint) (island->YMax - island->YMin); + float UScale = (float) texWidth / raiseToNextPowerOf2(texWidth); + float VScale = (float) texHeight / raiseToNextPowerOf2(texHeight); + // + uvScaleMat.setScale(CVector(UScale, - VScale, 0.f)); + uvScaleMat.setPos(CVector(0.f, VScale, 0.f)); + // + texturedMaterial.enableUserTexMat(0, true); + texturedMaterial.setUserTexMat(0, uvScaleMat * mat); + } + const CFrustum &frust = MainCam.getFrustum(); + + // + IDriver *driver = ((CDriverUser *) Driver)->getDriver(); + + driver->enableFog(true); + const CRGBA clearColor = CRGBA(0, 0, 127, 0); + driver->setupFog(frust.Far * 0.8f, frust.Far, clearColor); + CViewport vp; + vp.init(0.f, 0.f, 1.f, 1.f); + driver->setupViewport(vp); + CScissor scissor; + viewportToScissor(vp, scissor); + driver->setupScissor(scissor); + // + driver->setFrustum(frust.Left, frust.Right, frust.Bottom, frust.Top, frust.Near, frust.Far, frust.Perspective); + driver->setupViewMatrix(MainCam.getMatrix().inverted()); + driver->setupModelMatrix(CMatrix::Identity); + // + // + const CVector localFrustCorners[8] = + { + CVector(frust.Left, frust.Near, frust.Top), + CVector(frust.Right, frust.Near, frust.Top), + CVector(frust.Right, frust.Near, frust.Bottom), + CVector(frust.Left, frust.Near, frust.Bottom), + CVector(frust.Left * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near), + CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near), + CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near), + CVector(frust.Left * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near) + }; + // roughly compute covered zones + // + /* + sint frustZoneMinX = INT_MAX; + sint frustZoneMaxX = INT_MIN; + sint frustZoneMinY = INT_MAX; + sint frustZoneMaxY = INT_MIN; + for(uint k = 0; k < sizeofarray(localFrustCorners); ++k) + { + CVector corner = camMat * localFrustCorners[k]; + sint zoneX = (sint) (corner.x / 160.f) - zoneMinX; + sint zoneY = (sint) floorf(corner.y / 160.f) - zoneMinY; + frustZoneMinX = std::min(frustZoneMinX, zoneX); + frustZoneMinY = std::min(frustZoneMinY, zoneY); + frustZoneMaxX = std::max(frustZoneMaxX, zoneX); + frustZoneMaxY = std::max(frustZoneMaxY, zoneY); + } + */ + + const uint TRI_BATCH_SIZE = 10000; // batch size for rendering + static std::vector zones; + zones.clear(); + pw->getZones(zones); + for(uint k = 0; k < zones.size(); ++k) + { + zones[k]->render(vb, *driver, texturedMaterial, wiredMaterial, MainCam.getMatrix(), TRI_BATCH_SIZE, localFrustCorners); + } + } +} + +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** +// ******************************************************************** + +/* end of file */ \ No newline at end of file diff --git a/code/nel/src/3d/driver/opengl3/driver_glsl_pixel_program.cpp b/code/ryzom/client/src/main_loop_temp.h similarity index 63% rename from code/nel/src/3d/driver/opengl3/driver_glsl_pixel_program.cpp rename to code/ryzom/client/src/main_loop_temp.h index b859b8ce5..4f24972f7 100644 --- a/code/nel/src/3d/driver/opengl3/driver_glsl_pixel_program.cpp +++ b/code/ryzom/client/src/main_loop_temp.h @@ -1,37 +1,30 @@ -// NeL - MMORPG Framework -// 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 . - - -#include "driver_glsl_pixel_program.h" -#include "stdopengl.h" -#include "driver_opengl_extension.h" - -namespace NL3D -{ - CGLSLPixelProgram::CGLSLPixelProgram() : - CGLSLProgram() - { - type = PIXEL_PROGRAM; - } - - CGLSLPixelProgram::~CGLSLPixelProgram() - { - if( programId != 0 ) - nglDeleteProgram( programId ); - } -} - - +// Ryzom - MMORPG Framework +// 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 . + +#ifndef CL_MAIN_LOOP_TEMP_H +#define CL_MAIN_LOOP_TEMP_H + +#include + +// TMP TMP +void tempDumpValidPolys(); + +// TMP TMP +void tempDumpColPolys(); + +#endif // CL_MAIN_LOOP_TEMP_H + +/* end of file */ \ No newline at end of file diff --git a/code/ryzom/client/src/main_loop_utilities.cpp b/code/ryzom/client/src/main_loop_utilities.cpp new file mode 100644 index 000000000..7afba0a9f --- /dev/null +++ b/code/ryzom/client/src/main_loop_utilities.cpp @@ -0,0 +1,341 @@ +// Ryzom - MMORPG Framework +// 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 . + +#include +#include "main_loop_utilities.h" + +#include +#include + +#include "game_share/scenario_entry_points.h" + +#include "client_cfg.h" +#include "misc.h" +#include "global.h" +#include "world_database_manager.h" +#include "continent_manager.h" +#include "user_entity.h" +#include "view.h" +#include "ig_client.h" +#include "entities.h" +#include "input.h" +#include "sound_manager.h" +#include "camera.h" + +using namespace NLMISC; +using namespace NL3D; + +//--------------------------------------------------- +// Compare ClientCfg and LastClientCfg to know what we must update +//--------------------------------------------------- +void updateFromClientCfg() +{ + CClientConfig::setValues(); + ClientCfg.IsInvalidated = false; + + // GRAPHICS - GENERAL + //--------------------------------------------------- + if ((ClientCfg.Windowed != LastClientCfg.Windowed) || + (ClientCfg.Width != LastClientCfg.Width) || + (ClientCfg.Height != LastClientCfg.Height) || + (ClientCfg.Depth != LastClientCfg.Depth) || + (ClientCfg.Frequency != LastClientCfg.Frequency)) + { + setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, + ClientCfg.Windowed, ClientCfg.Frequency)); + } + + if (ClientCfg.DivideTextureSizeBy2 != LastClientCfg.DivideTextureSizeBy2) + { + if (ClientCfg.DivideTextureSizeBy2) + Driver->forceTextureResize(2); + else + Driver->forceTextureResize(1); + } + + //--------------------------------------------------- + if (ClientCfg.WaitVBL != LastClientCfg.WaitVBL) + { + if(ClientCfg.WaitVBL) + Driver->setSwapVBLInterval(1); + else + Driver->setSwapVBLInterval(0); + } + + // GRAPHICS - LANDSCAPE + //--------------------------------------------------- + if (ClientCfg.LandscapeThreshold != LastClientCfg.LandscapeThreshold) + { + if (Landscape) Landscape->setThreshold(ClientCfg.getActualLandscapeThreshold()); + } + + //--------------------------------------------------- + if (ClientCfg.LandscapeTileNear != LastClientCfg.LandscapeTileNear) + { + if (Landscape) Landscape->setTileNear(ClientCfg.LandscapeTileNear); + } + + //--------------------------------------------------- + if (Landscape) + { + if (ClientCfg.Vision != LastClientCfg.Vision) + { + if (!ClientCfg.Light) + { + // Not in an indoor ? + if (ContinentMngr.cur() && !ContinentMngr.cur()->Indoor) + { + // Refresh All Zone in streaming according to the refine position + std::vector zonesAdded; + std::vector zonesRemoved; + const R2::CScenarioEntryPoints::CCompleteIsland *ci = R2::CScenarioEntryPoints::getInstance().getCompleteIslandFromCoords(CVector2f((float) UserEntity->pos().x, (float) UserEntity->pos().y)); + Landscape->refreshAllZonesAround(View.refinePos(), ClientCfg.Vision + ExtraZoneLoadingVision, zonesAdded, zonesRemoved, ProgressBar, ci ? &(ci->ZoneIDs) : NULL); + LandscapeIGManager.unloadArrayZoneIG(zonesRemoved); + LandscapeIGManager.loadArrayZoneIG(zonesAdded); + } + } + } + } + + //--------------------------------------------------- + if (ClientCfg.Vision != LastClientCfg.Vision || ClientCfg.FoV!=LastClientCfg.FoV || + ClientCfg.Windowed != LastClientCfg.Windowed || ClientCfg.ScreenAspectRatio != LastClientCfg.ScreenAspectRatio ) + { + updateCameraPerspective(); + } + + //--------------------------------------------------- + if (Landscape) + { + if (ClientCfg.MicroVeget != LastClientCfg.MicroVeget) + { + if(ClientCfg.MicroVeget) + { + // if configured, enable the vegetable and load the texture. + Landscape->enableVegetable(true); + // Default setup. TODO later by gameDev. + Landscape->setVegetableWind(CVector(0.5, 0.5, 0).normed(), 0.5, 1, 0); + // Default setup. should work well for night/day transition in 30 minutes. + // Because all vegetables will be updated every 20 seconds => 90 steps. + Landscape->setVegetableUpdateLightingFrequency(1/20.f); + // Density (percentage to ratio) + Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f); + } + else + { + Landscape->enableVegetable(false); + } + } + } + + //--------------------------------------------------- + if (ClientCfg.MicroVegetDensity != LastClientCfg.MicroVegetDensity) + { + // Density (percentage to ratio) + if (Landscape) Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f); + } + + // GRAPHICS - SPECIAL EFFECTS + //--------------------------------------------------- + if (ClientCfg.FxNbMaxPoly != LastClientCfg.FxNbMaxPoly) + { + if (Scene->getGroupLoadMaxPolygon("Fx") != ClientCfg.FxNbMaxPoly) + Scene->setGroupLoadMaxPolygon("Fx", ClientCfg.FxNbMaxPoly); + } + + //--------------------------------------------------- + if (ClientCfg.Cloud != LastClientCfg.Cloud) + { + if (ClientCfg.Cloud) + { + InitCloudScape = true; + CloudScape = Scene->createCloudScape(); + } + else + { + if (CloudScape != NULL) + Scene->deleteCloudScape(CloudScape); + CloudScape = NULL; + } + } + + //--------------------------------------------------- + if (ClientCfg.CloudQuality != LastClientCfg.CloudQuality) + { + if (CloudScape != NULL) + CloudScape->setQuality(ClientCfg.CloudQuality); + } + + //--------------------------------------------------- + if (ClientCfg.CloudUpdate != LastClientCfg.CloudUpdate) + { + if (CloudScape != NULL) + CloudScape->setNbCloudToUpdateIn80ms(ClientCfg.CloudUpdate); + } + + //--------------------------------------------------- + if (ClientCfg.Shadows != LastClientCfg.Shadows) + { + // Enable/Disable Receive on Landscape + if(Landscape) + { + Landscape->enableReceiveShadowMap(ClientCfg.Shadows); + } + // Enable/Disable Cast for all entities + for(uint i=0;iupdateCastShadowMap(); + } + } + + // GRAPHICS - CHARACTERS + //--------------------------------------------------- + if (ClientCfg.SkinNbMaxPoly != LastClientCfg.SkinNbMaxPoly) + { + if (Scene->getGroupLoadMaxPolygon("Skin") != ClientCfg.SkinNbMaxPoly) + Scene->setGroupLoadMaxPolygon("Skin", ClientCfg.SkinNbMaxPoly); + } + + //--------------------------------------------------- + if (ClientCfg.NbMaxSkeletonNotCLod != LastClientCfg.NbMaxSkeletonNotCLod ) + { + Scene->setMaxSkeletonsInNotCLodForm(ClientCfg.NbMaxSkeletonNotCLod); + } + + //--------------------------------------------------- + if (ClientCfg.CharacterFarClip != LastClientCfg.CharacterFarClip) + { + // Nothing to do + } + + //--------------------------------------------------- + if (ClientCfg.HDEntityTexture != LastClientCfg.HDEntityTexture) + { + // Don't reload Texture, will be done at next Game Start + } + + // INTERFACE works + + + // INPUTS + //--------------------------------------------------- + if (ClientCfg.CursorSpeed != LastClientCfg.CursorSpeed) + SetMouseSpeed (ClientCfg.CursorSpeed); + + if (ClientCfg.CursorAcceleration != LastClientCfg.CursorAcceleration) + SetMouseAcceleration (ClientCfg.CursorAcceleration); + + if (ClientCfg.HardwareCursor != LastClientCfg.HardwareCursor) + { + if (ClientCfg.HardwareCursor != IsMouseCursorHardware()) + { + InitMouseWithCursor (ClientCfg.HardwareCursor); + } + } + + + // SOUND + //--------------------------------------------------- + bool mustReloadSoundMngrContinent= false; + + // disable/enable sound? + if (ClientCfg.SoundOn != LastClientCfg.SoundOn) + { + if (SoundMngr && !ClientCfg.SoundOn) + { + nlwarning("Deleting sound manager..."); + delete SoundMngr; + SoundMngr = NULL; + } + else if (SoundMngr == NULL && ClientCfg.SoundOn) + { + nlwarning("Creating sound manager..."); + SoundMngr = new CSoundManager(); + try + { + SoundMngr->init(NULL); + } + catch(const Exception &e) + { + nlwarning("init : Error when creating 'SoundMngr' : %s", e.what()); + SoundMngr = 0; + } + + // re-init with good SFX/Music Volume + if(SoundMngr) + { + SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume); + SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume); + } + } + else + { + nlwarning("Sound config error !"); + } + + mustReloadSoundMngrContinent= true; + } + + // change EAX? + if ( SoundMngr && LastClientCfg.SoundOn && + (ClientCfg.UseEax != LastClientCfg.UseEax) ) + { + SoundMngr->reset(); + + mustReloadSoundMngrContinent= true; + } + + // change SoundForceSoftwareBuffer? + if ( SoundMngr && LastClientCfg.SoundOn && + (ClientCfg.SoundForceSoftwareBuffer != LastClientCfg.SoundForceSoftwareBuffer) ) + { + SoundMngr->reset(); + + mustReloadSoundMngrContinent= true; + } + + // change MaxTrack? don't reset + if ( SoundMngr && LastClientCfg.SoundOn && + (ClientCfg.MaxTrack != LastClientCfg.MaxTrack)) + { + SoundMngr->getMixer()->changeMaxTrack(ClientCfg.MaxTrack); + } + + // change SoundFX Volume? don't reset + if (SoundMngr && ClientCfg.SoundSFXVolume != LastClientCfg.SoundSFXVolume) + { + SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume); + } + + // change Game Music Volume? don't reset + if (SoundMngr && ClientCfg.SoundGameMusicVolume != LastClientCfg.SoundGameMusicVolume) + { + SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume); + } + + // reload only if active and reseted + if (mustReloadSoundMngrContinent && SoundMngr && ContinentMngr.cur() && !ContinentMngr.cur()->Indoor && UserEntity) + { + SoundMngr->loadContinent(ContinentMngr.getCurrentContinentSelectName(), UserEntity->pos()); + } + + // Ok backup the new clientcfg + LastClientCfg = ClientCfg; +} + +/* end of file */ \ No newline at end of file diff --git a/code/ryzom/client/src/main_loop_utilities.h b/code/ryzom/client/src/main_loop_utilities.h new file mode 100644 index 000000000..d8ea3dedf --- /dev/null +++ b/code/ryzom/client/src/main_loop_utilities.h @@ -0,0 +1,32 @@ +// Ryzom - MMORPG Framework +// 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 . + +#ifndef CL_MAIN_LOOP_UTILITIES_H +#define CL_MAIN_LOOP_UTILITIES_H + +#include + +// Update Utilities (configuration etc) +// Only put utility update functions here that are used in the main loop. +// This is mainly for system configuration related functions +// such as config file changes. + +/// Compare ClientCfg and LastClientCfg to know what we must update +void updateFromClientCfg(); + +#endif // CL_MAIN_LOOP_UTILITIES_H + +/* end of file */ diff --git a/code/ryzom/client/src/ping.cpp b/code/ryzom/client/src/ping.cpp new file mode 100644 index 000000000..5a07a2b9d --- /dev/null +++ b/code/ryzom/client/src/ping.cpp @@ -0,0 +1,74 @@ +// Ryzom - MMORPG Framework +// 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 . + +#include +#include "ping.h" + +#include "interface_v3/interface_manager.h" +#include "time_client.h" + +using namespace NLMISC; +using namespace NLGUI; + +void CPing::init() +{ + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + if(pIM) + { + CCDBNodeLeaf *pNodeLeaf = CDBManager::getInstance()->getDbProp("SERVER:DEBUG_INFO:Ping", false); + if(pNodeLeaf) + { + ICDBNode::CTextId textId; + pNodeLeaf->addObserver(this, textId); + // nlwarning("CPing: cannot add the observer"); + } + else + nlwarning("CPing: 'SERVER:DEBUG_INFO:Ping' does not exist."); + } +} + +void CPing::release() +{ + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + if(pIM) + { + CCDBNodeLeaf *pNodeLeaf = CDBManager::getInstance()->getDbProp("SERVER:DEBUG_INFO:Ping", false); + if(pNodeLeaf) + { + ICDBNode::CTextId textId; + pNodeLeaf->removeObserver(this, textId); + } + else + nlwarning("CPing: 'SERVER:DEBUG_INFO:Ping' does not exist."); + } +} + +void CPing::update(NLMISC::ICDBNode* node) +{ + CCDBNodeLeaf *leaf = safe_cast(node); + uint32 before = (uint32)leaf->getValue32(); + uint32 current = (uint32)(0xFFFFFFFF & ryzomGetLocalTime()); + if(before > current) + { + //nlwarning("DB PING Pb before '%u' after '%u'.", before, current); + if(ClientCfg.Check) + nlstop; + } + _Ping = current - before; + _RdyToPing = true; +} + +/* end of file */ \ No newline at end of file diff --git a/code/ryzom/client/src/ping.h b/code/ryzom/client/src/ping.h new file mode 100644 index 000000000..46a7e2c13 --- /dev/null +++ b/code/ryzom/client/src/ping.h @@ -0,0 +1,62 @@ +// Ryzom - MMORPG Framework +// 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 . + +#ifndef CL_PING_H +#define CL_PING_H + +#include +#include + +/////////// +// CLASS // +/////////// +/** + * Class to manage the ping computed with the database. + * \author Guillaume PUZIN + * \author Nevrax France + * \date 2003 + */ +class CPing : public NLMISC::ICDBNode::IPropertyObserver +{ +private: + uint32 _Ping; + bool _RdyToPing; + +public: + // Constructor. + CPing() {_Ping = 0; _RdyToPing = true;} + // Destructor. + ~CPing() {;} + + // Add an observer on the database for the ping. + void init(); + + // Release the observer on the database for the ping. + void release(); + + // Method called when the ping message is back. + virtual void update(NLMISC::ICDBNode* node); + + // return the ping in ms. + uint32 getValue() {return _Ping;} + + void rdyToPing(bool rdy) {_RdyToPing = rdy;} + bool rdyToPing() const {return _RdyToPing;} +}; + +#endif // CL_PING_H + +/* end of file */ \ No newline at end of file diff --git a/code/ryzom/client/src/profiling.cpp b/code/ryzom/client/src/profiling.cpp new file mode 100644 index 000000000..a5a0f770f --- /dev/null +++ b/code/ryzom/client/src/profiling.cpp @@ -0,0 +1,160 @@ +// Ryzom - MMORPG Framework +// 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 . + +#include +#include "profiling.h" + +// NeL includes +#include + +// Project includes +#include "misc.h" +#include "sound_manager.h" + +/////////// +// USING // +/////////// +using namespace NLMISC; +using namespace NL3D; + +//////////// +// EXTERN // +//////////// +extern UDriver *Driver; + +///////////// +// GLOBALS // +///////////// +bool Profiling = false; // Are we in Profile mode? +uint ProfileNumFrame = 0; +bool WantProfiling = false; +bool ProfilingVBLock = false; +bool WantProfilingVBLock = false; + +// ******************************************************************** + +/// Test Profiling and run? +void testLaunchProfile() +{ + if(!WantProfiling) + return; + + // comes from ActionHandler + WantProfiling= false; + +#ifdef _PROFILE_ON_ + if( !Profiling ) + { + // start the bench. + NLMISC::CHTimer::startBench(); + ProfileNumFrame = 0; + Driver->startBench(); + if (SoundMngr) + SoundMngr->getMixer()->startDriverBench(); + // state + Profiling= true; + } + else + { + // end the bench. + if (SoundMngr) + SoundMngr->getMixer()->endDriverBench(); + NLMISC::CHTimer::endBench(); + Driver->endBench(); + + + // Display and save profile to a File. + CLog log; + CFileDisplayer fileDisplayer(NLMISC::CFile::findNewFile(getLogDirectory() + "profile.log")); + CStdDisplayer stdDisplayer; + log.addDisplayer(&fileDisplayer); + log.addDisplayer(&stdDisplayer); + // diplay + NLMISC::CHTimer::displayHierarchicalByExecutionPathSorted(&log, CHTimer::TotalTime, true, 48, 2); + NLMISC::CHTimer::displayHierarchical(&log, true, 48, 2); + NLMISC::CHTimer::displayByExecutionPath(&log, CHTimer::TotalTime); + NLMISC::CHTimer::display(&log, CHTimer::TotalTime); + NLMISC::CHTimer::display(&log, CHTimer::TotalTimeWithoutSons); + Driver->displayBench(&log); + + if (SoundMngr) + SoundMngr->getMixer()->displayDriverBench(&log); + + // state + Profiling= false; + } +#endif // #ifdef _PROFILE_ON_ +} + +// ******************************************************************** + +/// Test ProfilingVBLock and run? +void testLaunchProfileVBLock() +{ + // If running, must stop for this frame. + if(ProfilingVBLock) + { + std::vector strs; + Driver->endProfileVBHardLock(strs); + nlinfo("Profile VBLock"); + nlinfo("**************"); + for(uint i=0;iprofileVBHardAllocation(strs); + for(uint i=0;iendProfileIBLock(strs); + nlinfo("Profile Index Buffer Lock"); + nlinfo("**************"); + for(uint i=0;iprofileIBAllocation(strs); + for(uint i=0;istartProfileVBHardLock(); + Driver->startProfileIBLock(); + } +} + +/* end of file */ \ No newline at end of file diff --git a/code/nel/src/3d/driver/opengl3/driver_glsl_shader_base.h b/code/ryzom/client/src/profiling.h similarity index 60% rename from code/nel/src/3d/driver/opengl3/driver_glsl_shader_base.h rename to code/ryzom/client/src/profiling.h index 62b50e296..2499fa20b 100644 --- a/code/nel/src/3d/driver/opengl3/driver_glsl_shader_base.h +++ b/code/ryzom/client/src/profiling.h @@ -1,41 +1,36 @@ -// NeL - MMORPG Framework -// 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 . - - -#ifndef GLSL_SHADER_BASE_H -#define GLSL_SHADER_BASE_H - -#include "nel/3d/i_program.h" - -namespace NL3D -{ - /// Base class for OpenGL shader objects - class CGLSLShaderBase : public IProgram - { - public: - CGLSLShaderBase() : IProgram(){} - - ~CGLSLShaderBase(){} - - void shaderSource( const char *source ); - bool compile( std::string &log ); - }; -} - - -#endif - - +// Ryzom - MMORPG Framework +// 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 . + +#ifndef CL_PROFILING_H +#define CL_PROFILING_H + +#include + +extern bool Profiling; // Are we in Profile mode? +extern uint ProfileNumFrame; +extern bool WantProfiling; +extern bool ProfilingVBLock; +extern bool WantProfilingVBLock; + +/// Test Profiling and run? +void testLaunchProfile(); + +/// Test ProfilingVBLock and run? +void testLaunchProfileVBLock(); + +#endif // CL_PROFILING_H + +/* end of file */ \ No newline at end of file diff --git a/code/ryzom/client/src/projectile_manager.cpp b/code/ryzom/client/src/projectile_manager.cpp index 80db533c5..6b4e6c7c1 100644 --- a/code/ryzom/client/src/projectile_manager.cpp +++ b/code/ryzom/client/src/projectile_manager.cpp @@ -648,7 +648,7 @@ void CProjectileManager::CProjectile::shutDown(CCharacterCL *target) target->buildAlignMatrix(userMatrix); FX[k].forceSetUserMatrix(userMatrix); } - if (!FX[k].removeByID('STOP') && !FX[k].removeByID('main')) + if (!FX[k].removeByID(NELID("STOP")) && !FX[k].removeByID(NELID("main"))) { FX[k].activateEmitters(false); //nlwarning("Projectile with a particle system that has no 'STOP' emitter"); diff --git a/code/ryzom/client/src/r2/island_collision.cpp b/code/ryzom/client/src/r2/island_collision.cpp index 5018e41aa..fbc5a14ba 100644 --- a/code/ryzom/client/src/r2/island_collision.cpp +++ b/code/ryzom/client/src/r2/island_collision.cpp @@ -429,7 +429,7 @@ CPackedWorld *CIslandCollision::reloadPackedIsland(const CScenarioEntryPoints::C try { CIFile f(CPath::lookup(islandDesc.Island + ".island_hm")); - f.serialCheck((uint32) 'MHSI'); + f.serialCheck(NELID("MHSI")); f.serial(_HeightMap); } catch(const Exception &e) diff --git a/code/ryzom/client/src/release.cpp b/code/ryzom/client/src/release.cpp index 0c975aebe..dae95767c 100644 --- a/code/ryzom/client/src/release.cpp +++ b/code/ryzom/client/src/release.cpp @@ -35,6 +35,7 @@ #include "nel/3d/u_scene.h" #include "nel/3d/u_visual_collision_manager.h" #include "nel/3d/u_shape_bank.h" +#include "nel/3d/stereo_hmd.h" // Client #include "global.h" #include "release.h" @@ -467,8 +468,6 @@ void releaseOutGame() // flush the server string cache STRING_MANAGER::CStringManagerClient::instance()->flushStringCache(); - ClientCfg.release (); - // Disconnect the client from the server. NetMngr.disconnect(); @@ -559,6 +558,15 @@ void release() CEntityAnimationManager::delInstance(); EAM= NULL; + nldebug("VR [C]: VR Shutting down"); + if (StereoDisplay) + { + delete StereoDisplay; + StereoDisplay = NULL; + StereoHMD = NULL; + } + IStereoDisplay::releaseAllLibraries(); + // Delete the driver. if(Driver) { diff --git a/code/ryzom/client/src/string_manager_client.h b/code/ryzom/client/src/string_manager_client.h index 89e05acd0..14f541c10 100644 --- a/code/ryzom/client/src/string_manager_client.h +++ b/code/ryzom/client/src/string_manager_client.h @@ -341,8 +341,8 @@ private: void serial(NLMISC::IStream &f) { - f.serialCheck((uint32)'_RTS'); - f.serialCheck((uint32)'KCAP'); + f.serialCheck(NELID("_RTS")); + f.serialCheck(NELID("KCAP")); f.serialVersion(0); f.serial(PackedVersion); f.serial(LanguageCode); diff --git a/code/ryzom/client/src/timed_fx_manager.cpp b/code/ryzom/client/src/timed_fx_manager.cpp index 6ea6f273b..89b71974f 100644 --- a/code/ryzom/client/src/timed_fx_manager.cpp +++ b/code/ryzom/client/src/timed_fx_manager.cpp @@ -544,7 +544,7 @@ void CTimedFXManager::CManagedFX::shutDown(NL3D::UScene *scene, CFXManager &fxMa // fx isn't spwaned, so must tell fx to stop its emitters if (Instance.isSystemPresent() && Instance.isValid()) { - if (!Instance.removeByID('main') && !Instance.removeByID('STOP')) + if (!Instance.removeByID(NELID("main")) && !Instance.removeByID(NELID("STOP"))) { // if a specific emitter has not be tagged, just stop all emitters if there's no better solution Instance.activateEmitters(false); diff --git a/code/ryzom/client/src/view.cpp b/code/ryzom/client/src/view.cpp index ded81013d..4bc52af08 100644 --- a/code/ryzom/client/src/view.cpp +++ b/code/ryzom/client/src/view.cpp @@ -183,7 +183,6 @@ CVector CView::currentViewPos() const //----------------------------------------------- // currentView : -// Set the user position. //----------------------------------------------- CVector CView::currentView() const { @@ -200,6 +199,14 @@ CVector CView::currentView() const return _View; }// currentView // +NLMISC::CQuat CView::currentViewQuat() const +{ + CMatrix mat; + mat.setRot(CVector::I, currentView(), CVector::K); + mat.normalize(CMatrix::YZX); + return mat.getRot(); +} + //----------------------------------------------- // currentCameraTarget : //----------------------------------------------- diff --git a/code/ryzom/client/src/view.h b/code/ryzom/client/src/view.h index 69fcea994..e1c57d4ca 100644 --- a/code/ryzom/client/src/view.h +++ b/code/ryzom/client/src/view.h @@ -115,6 +115,8 @@ public: CVector currentViewPos() const; // Return the current view (rear or normal) CVector currentView() const; + // Return the current view as a quaternion + NLMISC::CQuat currentViewQuat() const; // Return the current Camera Target (for 3rd person only. 1st person: return currentViewPos()) CVector currentCameraTarget() const; diff --git a/code/ryzom/common/data_common/database.xml b/code/ryzom/common/data_common/database.xml index 6157693c6..fc0d1d209 100644 --- a/code/ryzom/common/data_common/database.xml +++ b/code/ryzom/common/data_common/database.xml @@ -1,1665 +1,1665 @@ - - - - - - - inline void _setProp(CCDBSynchronised &db, - ICDBStructNode *node, TCharConnectionState value, bool - forceSending = false) { db.x_setProp(node, uint64(value), - forceSending); } inline void _getProp(const CCDBSynchronised - &db, ICDBStructNode *node, TCharConnectionState - &value) { value = - (TCharConnectionState)db.x_getProp(node); } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + inline void _setProp(CCDBSynchronised &db, + ICDBStructNode *node, TCharConnectionState value, bool + forceSending = false) { db.x_setProp(node, uint64(value), + forceSending); } inline void _getProp(const CCDBSynchronised + &db, ICDBStructNode *node, TCharConnectionState + &value) { value = + (TCharConnectionState)db.x_getProp(node); } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/ryzom/common/data_common/msg.xml b/code/ryzom/common/data_common/msg.xml index df2011edf..3fa75650e 100644 --- a/code/ryzom/common/data_common/msg.xml +++ b/code/ryzom/common/data_common/msg.xml @@ -1,1165 +1,1165 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/ryzom/common/src/game_share/persistent_data_template.h b/code/ryzom/common/src/game_share/persistent_data_template.h index 87a110d16..560603f0a 100644 --- a/code/ryzom/common/src/game_share/persistent_data_template.h +++ b/code/ryzom/common/src/game_share/persistent_data_template.h @@ -325,9 +325,11 @@ static _TOKENS_CLASSNAME _TOKENS_OBJNAME; #else +#ifdef NL_OS_WINDOWS #pragma message( " ") #pragma message( "NON-OPTIMISED: Persistent data class " NL_MACRO_TO_STR(PERSISTENT_CLASS) " not using a token family") #pragma message( " ") +#endif #endif diff --git a/code/ryzom/common/src/game_share/security_check.cpp b/code/ryzom/common/src/game_share/security_check.cpp index bbc0d46d1..6acd2aeac 100644 --- a/code/ryzom/common/src/game_share/security_check.cpp +++ b/code/ryzom/common/src/game_share/security_check.cpp @@ -43,7 +43,7 @@ void CSecurityCheckForFastDisconnection::forwardSecurityCode(NLMISC::IStream& ms } // -CSecurityCode CSecurityCheckForFastDisconnection::encode(char *passPhrase) +CSecurityCode CSecurityCheckForFastDisconnection::encode(const char *passPhrase) { if (!passPhrase) throw Exception("Null passPhrase"); @@ -56,7 +56,7 @@ CSecurityCode CSecurityCheckForFastDisconnection::encode(char *passPhrase) } // -void CSecurityCheckForFastDisconnection::check(char *passPhrase) +void CSecurityCheckForFastDisconnection::check(const char *passPhrase) { if (SecurityCode != encode(passPhrase)) throw Exception("Check not passed"); diff --git a/code/ryzom/common/src/game_share/security_check.h b/code/ryzom/common/src/game_share/security_check.h index 60c736f72..640fec93a 100644 --- a/code/ryzom/common/src/game_share/security_check.h +++ b/code/ryzom/common/src/game_share/security_check.h @@ -61,9 +61,9 @@ public: /// Set cookie void setCookie(const NLNET::CLoginCookie& cookie) { Block.Cookie.set(cookie.getUserAddr(), cookie.getUserKey(), cookie.getUserId()); } // don't use the default generated bitwise assignment operator, because of padding junk that would be copied /// Return the security code - CSecurityCode encode(char *passPhrase); + CSecurityCode encode(const char *passPhrase); /// Check the security code - void check(char *passPhrase); + void check(const char *passPhrase); /// Read some data from stream void receiveSecurityCode(NLMISC::IStream& msgin); diff --git a/code/ryzom/server/src/ai_data_service/pacs_scan.cpp b/code/ryzom/server/src/ai_data_service/pacs_scan.cpp index 6a15900d0..b593c7a37 100644 --- a/code/ryzom/server/src/ai_data_service/pacs_scan.cpp +++ b/code/ryzom/server/src/ai_data_service/pacs_scan.cpp @@ -2277,7 +2277,7 @@ public: sint32 xmax = (sint32) max.x(); sint32 ymin = (sint32) (sint16) min.y(); sint32 ymax = (sint32) (sint16) max.y(); - output.serialCheck((uint32) 'OBSI'); + output.serialCheck(NELID("OBSI")); output.serial(xmin); output.serial(xmax); output.serial(ymin); diff --git a/code/ryzom/server/src/ai_service/commands.cpp b/code/ryzom/server/src/ai_service/commands.cpp index 92193e6c5..07e9023bf 100644 --- a/code/ryzom/server/src/ai_service/commands.cpp +++ b/code/ryzom/server/src/ai_service/commands.cpp @@ -1700,7 +1700,7 @@ NLMISC_COMMAND(scriptHex,"execute a hex-encoded script for a group in the given return true; } -static char* hexEncoderTcl = +static const char* hexEncoderTcl = "proc copy_encoded {} {" " # Get the args from the text fields" " set group [ .group.name get 1.0 end ]" diff --git a/code/ryzom/server/src/ai_share/ai_spawn_commands.h b/code/ryzom/server/src/ai_share/ai_spawn_commands.h index 96f2d99a0..059f08f1b 100644 --- a/code/ryzom/server/src/ai_share/ai_spawn_commands.h +++ b/code/ryzom/server/src/ai_share/ai_spawn_commands.h @@ -1,59 +1,59 @@ -// Ryzom - MMORPG Framework -// 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 . - - - +// Ryzom - MMORPG Framework +// 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 . + + + #ifndef RYAI_SPAWN_COMMANDS_H #define RYAI_SPAWN_COMMANDS_H - -#include "nel/misc/types_nl.h" -#include "nel/misc/debug.h" - -#include - - -//class CAISpawnCtrl -//{ -//public: -// static bool spawn (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_spawn(aiInstance, name); } -// static bool spawnMap (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_spawnMap(aiInstance, name); } -// static bool spawnMgr (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_spawnMgr(aiInstance, name); } -// static bool spawnGrp (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_spawnGrp(aiInstance, name); } -// static bool spawnAll (int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_spawnAll(aiInstance); } -// -// static bool despawn (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_despawn(aiInstance, name); } -// static bool despawnMap (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_despawnMap(aiInstance, name); } -// static bool despawnMgr (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_despawnMgr(aiInstance, name); } -// static bool despawnGrp (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_despawnGrp(aiInstance, name); } -// static bool despawnAll (int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_despawnAll(aiInstance); } -// -//protected: -// virtual bool _spawn (int aiInstance, const std::string &name)=0; -// virtual bool _spawnMap (int aiInstance, const std::string &name)=0; -// virtual bool _spawnMgr (int aiInstance, const std::string &name)=0; -// virtual bool _spawnGrp (int aiInstance, const std::string &name)=0; -// virtual bool _spawnAll (int aiInstance)=0; -// -// virtual bool _despawn (int aiInstance, const std::string &name)=0; -// virtual bool _despawnMap (int aiInstance, const std::string &name)=0; -// virtual bool _despawnMgr (int aiInstance, const std::string &name)=0; -// virtual bool _despawnGrp (int aiInstance, const std::string &name)=0; -// virtual bool _despawnAll (int aiInstance)=0; -// -// static CAISpawnCtrl *_instance; -//}; - -#endif + +#include "nel/misc/types_nl.h" +#include "nel/misc/debug.h" + +#include + + +//class CAISpawnCtrl +//{ +//public: +// static bool spawn (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_spawn(aiInstance, name); } +// static bool spawnMap (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_spawnMap(aiInstance, name); } +// static bool spawnMgr (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_spawnMgr(aiInstance, name); } +// static bool spawnGrp (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_spawnGrp(aiInstance, name); } +// static bool spawnAll (int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_spawnAll(aiInstance); } +// +// static bool despawn (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_despawn(aiInstance, name); } +// static bool despawnMap (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_despawnMap(aiInstance, name); } +// static bool despawnMgr (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_despawnMgr(aiInstance, name); } +// static bool despawnGrp (const std::string &name, int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_despawnGrp(aiInstance, name); } +// static bool despawnAll (int aiInstance=-1) { nlassert(_instance!=NULL); return _instance->_despawnAll(aiInstance); } +// +//protected: +// virtual bool _spawn (int aiInstance, const std::string &name)=0; +// virtual bool _spawnMap (int aiInstance, const std::string &name)=0; +// virtual bool _spawnMgr (int aiInstance, const std::string &name)=0; +// virtual bool _spawnGrp (int aiInstance, const std::string &name)=0; +// virtual bool _spawnAll (int aiInstance)=0; +// +// virtual bool _despawn (int aiInstance, const std::string &name)=0; +// virtual bool _despawnMap (int aiInstance, const std::string &name)=0; +// virtual bool _despawnMgr (int aiInstance, const std::string &name)=0; +// virtual bool _despawnGrp (int aiInstance, const std::string &name)=0; +// virtual bool _despawnAll (int aiInstance)=0; +// +// static CAISpawnCtrl *_instance; +//}; + +#endif diff --git a/code/ryzom/server/src/ai_share/world_map.cpp b/code/ryzom/server/src/ai_share/world_map.cpp index fae9ad50f..eae84acbf 100644 --- a/code/ryzom/server/src/ai_share/world_map.cpp +++ b/code/ryzom/server/src/ai_share/world_map.cpp @@ -553,7 +553,7 @@ void CWorldMap::clear() void CWorldMap::serial(NLMISC::IStream &f) { - f.serialCheck((uint32)'WMAP'); + f.serialCheck(NELID("WMAP")); // Version // 0: initial version diff --git a/code/ryzom/server/src/ai_share/world_map.h b/code/ryzom/server/src/ai_share/world_map.h index 48dcfee77..f9e46ecfc 100644 --- a/code/ryzom/server/src/ai_share/world_map.h +++ b/code/ryzom/server/src/ai_share/world_map.h @@ -1633,18 +1633,27 @@ CTopology::CTopology() { } +// convert a 2 characters string to uint16 +#ifdef NL_LITTLE_ENDIAN +# define NELID16(x) (uint16((x[0] << 8) | (x[1]))) +#else +# define NELID16(x) (uint16((x[1] << 8) | (x[0]))) +#endif + + + inline void CTopology::serial(NLMISC::IStream& f) { uint version = 0; - uint16 check = (uint16)'Tp'; + uint16 check = NELID16("Tp"); f.serial(check); - if (check != (uint16)'TP') + if (check != NELID16("TP")) { - nlassert(check == (uint16)'Tp'); + nlassert(check == NELID16("Tp")); version = f.serialVersion(3); } @@ -2285,7 +2294,7 @@ sint CWhiteCell::getHeight(CWorldPosition const& wpos) const inline void CWhiteCell::serial(NLMISC::IStream& f) { - f.serialCheck((uint16)'WC'); + f.serialCheck(NELID16("WC")); if (f.isReading()) _HeightMap = I16x16Layer::load(f); else diff --git a/code/ryzom/server/src/entities_game_service/fame_pd.cpp b/code/ryzom/server/src/entities_game_service/fame_pd.cpp index cf27d6459..db2104c5d 100644 --- a/code/ryzom/server/src/entities_game_service/fame_pd.cpp +++ b/code/ryzom/server/src/entities_game_service/fame_pd.cpp @@ -21,7 +21,7 @@ namespace EGSPD { -static const struct { char* Name; CFameTrend::TFameTrend Value; } TFameTrendConvert[] = +static const struct { const char* Name; CFameTrend::TFameTrend Value; } TFameTrendConvert[] = { { "FameUpward", CFameTrend::FameUpward }, { "FameDownward", CFameTrend::FameDownward }, diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.cpp b/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.cpp index f62af0007..03a105445 100644 --- a/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.cpp +++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.cpp @@ -494,7 +494,7 @@ bool CGuildMemberModule::canAffectGrade(EGSPD::CGuildGrade::TGuildGrade)const CMissionGuild * CGuildMemberModule::pickMission( TAIAlias alias ) { /// todo guild mission - return false; + return NULL; } //---------------------------------------------------------------------------- diff --git a/code/ryzom/server/src/entities_game_service/harvest_source.cpp b/code/ryzom/server/src/entities_game_service/harvest_source.cpp index 6c5f85a61..dcae55a60 100644 --- a/code/ryzom/server/src/entities_game_service/harvest_source.cpp +++ b/code/ryzom/server/src/entities_game_service/harvest_source.cpp @@ -1270,7 +1270,7 @@ bool forageTestDoExtract( testSource->extractMaterial( req, abs, ForageQualityCeilingFactor.get(), ForageQualitySlowFactor.get(), res, successFactor, 0, row, propDrop ); fprintf( f, "%g;%g;%g;%g;%g;%g;%g;%g;%g;%u;%u;\n", res[CHarvestSource::A], res[CHarvestSource::Q], - testSource->getD(), testSource->getE(), 0 /*testSource->getC()*/, + testSource->getD(), testSource->getE(), 0.f /*testSource->getC()*/, reqS, reqA, reqQ, testSource->quantity(), testSource->getImpactScheme()*5, 127 ); if ( (!eventD) && (testSource->getD() > 127) ) diff --git a/code/ryzom/server/src/entities_game_service/phrase_manager/combat_action.cpp b/code/ryzom/server/src/entities_game_service/phrase_manager/combat_action.cpp index ac50c52cd..c6cddb5e5 100644 --- a/code/ryzom/server/src/entities_game_service/phrase_manager/combat_action.cpp +++ b/code/ryzom/server/src/entities_game_service/phrase_manager/combat_action.cpp @@ -29,11 +29,8 @@ CCombatAction * CCombatAIActionFactory::buildAiAction(const CStaticAiAction *aiA nlassert(phrase); #endif const AI_ACTION::TAiActionType actionType = aiAction->getType(); - if (actionType != AI_ACTION::Melee && actionType != AI_ACTION::Range) - { - return false; - } - + if (actionType != AI_ACTION::Melee && actionType != AI_ACTION::Range) return NULL; + AI_ACTION::TAiEffectType effectType = aiAction->getData().Combat.EffectFamily; //get appropriate factory diff --git a/code/ryzom/server/src/entities_game_service/phrase_manager/fg_prospection_phrase.cpp b/code/ryzom/server/src/entities_game_service/phrase_manager/fg_prospection_phrase.cpp index fbb16a296..010176023 100644 --- a/code/ryzom/server/src/entities_game_service/phrase_manager/fg_prospection_phrase.cpp +++ b/code/ryzom/server/src/entities_game_service/phrase_manager/fg_prospection_phrase.cpp @@ -1936,7 +1936,7 @@ void CDepositMapsBatchTask::run() CSString res; disp.write( res ); res = res.replace( "\n", "
\n" ); - fprintf( outputF, res.c_str() ); + fprintf( outputF, "%s", res.c_str() ); // Close files fclose( inputF ); diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character_interface.h b/code/ryzom/server/src/entities_game_service/player_manager/character_interface.h index ecc133f54..7e6a47064 100644 --- a/code/ryzom/server/src/entities_game_service/player_manager/character_interface.h +++ b/code/ryzom/server/src/entities_game_service/player_manager/character_interface.h @@ -22,13 +22,17 @@ class CEntityState; class COfflineEntityState; class CCharacterRespawnPoints; class CFarPosition; -class NLNET::CMessage; class CModuleParent; +namespace NLNET +{ + class CMessage; +} + namespace R2 { struct TUserRole; -}; +} class CRingRewardPoints; diff --git a/code/ryzom/server/src/general_utilities_service/stat_char_commands.cpp b/code/ryzom/server/src/general_utilities_service/stat_char_commands.cpp index 1db7c68b8..a8203bb03 100644 --- a/code/ryzom/server/src/general_utilities_service/stat_char_commands.cpp +++ b/code/ryzom/server/src/general_utilities_service/stat_char_commands.cpp @@ -349,13 +349,13 @@ static std::string getActiveOutputPath() if (TheCharScanScriptFile==NULL) { nlwarning("There is no active script file right now from which to extract output directory"); - return false; + return ""; } bool isOK=true; // write the current script file to a tmp file isOK=TheCharScanScriptFile->writeToFile(TmpScriptFileName); - if (!isOK) return false; + if (!isOK) return ""; // create a new script object and assign the tmp file to it CCharScanScript script; diff --git a/code/ryzom/server/src/input_output_service/messages.cpp b/code/ryzom/server/src/input_output_service/messages.cpp index 1abec0011..4af959590 100644 --- a/code/ryzom/server/src/input_output_service/messages.cpp +++ b/code/ryzom/server/src/input_output_service/messages.cpp @@ -336,7 +336,7 @@ void cbImpulsionFilter( CMessage& msgin, const string &serviceName, TServiceId s } // impulsionFilter // -static char*DebugChatModeName[] = +static const char* DebugChatModeName[] = { "say", "shout", diff --git a/code/ryzom/server/src/input_output_service/parameter_traits.cpp b/code/ryzom/server/src/input_output_service/parameter_traits.cpp index 8eecfd1de..a0b45fcf7 100644 --- a/code/ryzom/server/src/input_output_service/parameter_traits.cpp +++ b/code/ryzom/server/src/input_output_service/parameter_traits.cpp @@ -42,7 +42,7 @@ extern CVariable VerboseStringManager; #define LOG if (!VerboseStringManager) {} else nlinfo -char *OperatorNames[] = +const char *OperatorNames[] = { "equal", "notEqual", diff --git a/code/ryzom/server/src/logger_service/logger_service.cpp b/code/ryzom/server/src/logger_service/logger_service.cpp index 245fe4c89..dba4cae57 100644 --- a/code/ryzom/server/src/logger_service/logger_service.cpp +++ b/code/ryzom/server/src/logger_service/logger_service.cpp @@ -521,9 +521,7 @@ public: BsiGlobal); saveFile.FileName = threadResult.OutputFilename; - char *newLine="\n"; - - + const char *newLine="\n"; list::const_iterator first(threadResult.Lines->begin()), last(threadResult.Lines->end()); for (uint32 localCounter = 0; first != last; ++first, ++localCounter) diff --git a/code/ryzom/server/src/pd_lib/db_delta_file.cpp b/code/ryzom/server/src/pd_lib/db_delta_file.cpp index ded4e57c1..4ca800256 100644 --- a/code/ryzom/server/src/pd_lib/db_delta_file.cpp +++ b/code/ryzom/server/src/pd_lib/db_delta_file.cpp @@ -259,7 +259,7 @@ bool CDBDeltaFile::preload() */ bool CDBDeltaFile::serialHeader() { - serialCheck((uint32)'DbDt'); + serialCheck(NELID("DbDt")); uint version = serialVersion(0); if (isReading()) @@ -280,7 +280,7 @@ bool CDBDeltaFile::serialHeader() serial(_Header); } - serialCheck((uint32)'Data'); + serialCheck(NELID("Data")); _DataStart = ftell(_File); diff --git a/code/ryzom/server/src/pd_lib/db_delta_file.h b/code/ryzom/server/src/pd_lib/db_delta_file.h index a8d8776cf..f33feaa52 100644 --- a/code/ryzom/server/src/pd_lib/db_delta_file.h +++ b/code/ryzom/server/src/pd_lib/db_delta_file.h @@ -189,7 +189,7 @@ private: void serial(NLMISC::IStream& s) { - s.serialCheck((uint32)'DHdr'); + s.serialCheck(NELID("DHdr")); uint version = s.serialVersion(0); s.serial(RowSize); diff --git a/code/ryzom/server/src/pd_lib/db_reference_file.cpp b/code/ryzom/server/src/pd_lib/db_reference_file.cpp index 7ae9ecb1c..edb8c596e 100644 --- a/code/ryzom/server/src/pd_lib/db_reference_file.cpp +++ b/code/ryzom/server/src/pd_lib/db_reference_file.cpp @@ -483,7 +483,7 @@ bool CDBReferenceFile::read(uint32 index, uint8* rowdata) */ bool CDBReferenceFile::serialHeader() { - serialCheck((uint32)'DbRf'); + serialCheck(NELID("DbRf")); uint version = serialVersion(0); if (isReading()) @@ -504,7 +504,7 @@ bool CDBReferenceFile::serialHeader() serial(_Header); } - serialCheck((uint32)'Data'); + serialCheck(NELID("Data")); _DataStart = ftell(_File); diff --git a/code/ryzom/server/src/pd_lib/db_reference_file.h b/code/ryzom/server/src/pd_lib/db_reference_file.h index 72fcffb88..269e5278f 100644 --- a/code/ryzom/server/src/pd_lib/db_reference_file.h +++ b/code/ryzom/server/src/pd_lib/db_reference_file.h @@ -199,7 +199,7 @@ private: void serial(NLMISC::IStream& s) { - s.serialCheck((uint32)'RHdr'); + s.serialCheck(NELID("RHdr")); uint version = s.serialVersion(0); s.serial(BaseIndex); diff --git a/code/ryzom/server/src/pd_lib/pd_messages.h b/code/ryzom/server/src/pd_lib/pd_messages.h index 0dac4215c..25ea12c4b 100644 --- a/code/ryzom/server/src/pd_lib/pd_messages.h +++ b/code/ryzom/server/src/pd_lib/pd_messages.h @@ -1436,7 +1436,7 @@ inline uint32 CDbMessage::getMessageHeaderSize() */ inline void CUpdateLog::serial(NLMISC::IStream& f) { - f.serialCheck((uint32)'ULOG'); + f.serialCheck(NELID("ULOG")); uint version = f.serialVersion(1); diff --git a/code/ryzom/server/src/pd_lib/pd_server_utils.cpp b/code/ryzom/server/src/pd_lib/pd_server_utils.cpp index 9b27b1d23..1ca303b0f 100644 --- a/code/ryzom/server/src/pd_lib/pd_server_utils.cpp +++ b/code/ryzom/server/src/pd_lib/pd_server_utils.cpp @@ -331,7 +331,7 @@ void CDatabaseState::serial(NLMISC::IStream& s) { s.xmlPush("database_state"); - s.serialCheck((uint32)'DBST'); + s.serialCheck(NELID("DBST")); uint version = s.serialVersion(0); s.xmlPush("name"); diff --git a/code/ryzom/server/src/pd_lib/pd_server_utils.h b/code/ryzom/server/src/pd_lib/pd_server_utils.h index 97f0ebec0..ac67e8a7a 100644 --- a/code/ryzom/server/src/pd_lib/pd_server_utils.h +++ b/code/ryzom/server/src/pd_lib/pd_server_utils.h @@ -60,7 +60,7 @@ public: { s.xmlPush("reference"); - s.serialCheck((uint32)'RIDX'); + s.serialCheck(NELID("RIDX")); uint version = s.serialVersion(0); s.xmlPush("database"); diff --git a/code/ryzom/server/src/pd_lib/pd_string_mapper.cpp b/code/ryzom/server/src/pd_lib/pd_string_mapper.cpp index f4277b61a..184d4bb7f 100644 --- a/code/ryzom/server/src/pd_lib/pd_string_mapper.cpp +++ b/code/ryzom/server/src/pd_lib/pd_string_mapper.cpp @@ -73,7 +73,7 @@ void CPDStringMapper::setMapping(const std::string& str, uint32 id) */ void CPDStringMapper::serial(NLMISC::IStream& f) { - f.serialCheck((uint32)'PDSM'); + f.serialCheck(NELID("PDSM")); uint version = f.serialVersion(0); diff --git a/code/ryzom/server/src/pd_lib/pd_utils.h b/code/ryzom/server/src/pd_lib/pd_utils.h index 07744d3ad..73a0268d8 100644 --- a/code/ryzom/server/src/pd_lib/pd_utils.h +++ b/code/ryzom/server/src/pd_lib/pd_utils.h @@ -714,7 +714,7 @@ public: void serial(NLMISC::IStream& f) { - f.serialCheck((uint32)'IALC'); + f.serialCheck(NELID("IALC")); f.serialVersion(0); f.serial(_NextIndex); diff --git a/code/ryzom/server/src/pd_support_service/daily_commands.cpp b/code/ryzom/server/src/pd_support_service/daily_commands.cpp index 429823160..e3f6d718c 100644 --- a/code/ryzom/server/src/pd_support_service/daily_commands.cpp +++ b/code/ryzom/server/src/pd_support_service/daily_commands.cpp @@ -104,7 +104,7 @@ public: FILE* fileHandle= fopen(DailyActivityLogFileName,"ab"); nlassert(fileHandle!=NULL); fprintf(fileHandle,"%02u/%02u/%u CDailyTaskScheduler: Started: %02u:%02u, Finished: %02u:%02u, Executed %u commands Started %u Jobs\n", - ptm->tm_mday, ptm->tm_mon+1, ptm->tm_year+1900, startTime/3600%24, startTime/60%60, endTime/3600%24, endTime/60%60, commandsVar==NULL?0:commandsVar->size(), jobsRemaining ); + ptm->tm_mday, ptm->tm_mon+1, ptm->tm_year+1900, (uint)startTime/3600%24, (uint)startTime/60%60, (uint)endTime/3600%24, (uint)endTime/60%60, commandsVar==NULL?0:commandsVar->size(), jobsRemaining ); nlinfo("JobManager state: %s",CJobManager::getInstance()->getStatus().c_str()); fclose(fileHandle); } diff --git a/code/ryzom/server/src/pd_support_service/stat_char_commands.cpp b/code/ryzom/server/src/pd_support_service/stat_char_commands.cpp index 611bd9b6b..ed5641455 100644 --- a/code/ryzom/server/src/pd_support_service/stat_char_commands.cpp +++ b/code/ryzom/server/src/pd_support_service/stat_char_commands.cpp @@ -518,13 +518,13 @@ static std::string getActiveOutputPath() if (TheCharScanScriptFile==NULL) { nlwarning("There is no active script file right now from which to extract output directory"); - return false; + return ""; } bool isOK=true; // write the current script file to a tmp file isOK=TheCharScanScriptFile->writeToFile(TmpScriptFileName); - if (!isOK) return false; + if (!isOK) return ""; // create a new script object and assign the tmp file to it CCharScanScriptFile script; diff --git a/code/ryzom/server/src/persistant_data_service/db_manager.cpp b/code/ryzom/server/src/persistant_data_service/db_manager.cpp index 3160b9689..6acdf687c 100644 --- a/code/ryzom/server/src/persistant_data_service/db_manager.cpp +++ b/code/ryzom/server/src/persistant_data_service/db_manager.cpp @@ -176,7 +176,7 @@ CTimestamp CDbManager::_LastUpdateTime; */ CDatabase* CDbManager::createDatabase(TDatabaseId id, CLog* log) { - CHECK_DB_MGR_INIT(createDatabase, false); + CHECK_DB_MGR_INIT(createDatabase, NULL); // check db doesn't exist yet CDatabase* db = getDatabase(id); @@ -229,7 +229,7 @@ bool CDbManager::deleteDatabase(TDatabaseId id, CLog* log) */ CDatabase* CDbManager::loadDatabase(TDatabaseId id, const string& description, CLog* log) { - CHECK_DB_MGR_INIT(loadDatabase, false); + CHECK_DB_MGR_INIT(loadDatabase, NULL); nlinfo("CDbManager::loadDatabase(): load/setup database '%d'", id); diff --git a/code/ryzom/server/src/persistant_data_service/pds_database.cpp b/code/ryzom/server/src/persistant_data_service/pds_database.cpp index 13202bb1e..66b272d5c 100644 --- a/code/ryzom/server/src/persistant_data_service/pds_database.cpp +++ b/code/ryzom/server/src/persistant_data_service/pds_database.cpp @@ -1195,7 +1195,7 @@ CDatabase* CDatabase::adapt(const string& description) if (!buildReference()) { PDS_WARNING("adapt(): failed to buildReference()"); - return false; + return NULL; } } diff --git a/code/ryzom/server/src/persistant_data_service/pds_type.cpp b/code/ryzom/server/src/persistant_data_service/pds_type.cpp index eb8ea5f19..46f9fb924 100644 --- a/code/ryzom/server/src/persistant_data_service/pds_type.cpp +++ b/code/ryzom/server/src/persistant_data_service/pds_type.cpp @@ -194,7 +194,7 @@ string CType::getIndexName(TEnumValue value, bool verbose) const if (!isIndex()) { PDS_WARNING("getIndexName(): type is not an index"); - return false; + return ""; } if (isEnum()) diff --git a/code/ryzom/server/src/server_share/light_ig_loader.cpp b/code/ryzom/server/src/server_share/light_ig_loader.cpp index f9fd3aa1f..de29ad949 100644 --- a/code/ryzom/server/src/server_share/light_ig_loader.cpp +++ b/code/ryzom/server/src/server_share/light_ig_loader.cpp @@ -114,7 +114,7 @@ void CLightIGLoader::loadIG(const string &filename) // Serial a header - _File.serialCheck ((uint32)'TPRG'); + _File.serialCheck (NELID("TPRG")); // Serial a version number sint version = _File.serialVersion (5); diff --git a/code/ryzom/server/src/shard_unifier_service/name_manager.cpp b/code/ryzom/server/src/shard_unifier_service/name_manager.cpp index ff05659c1..5b50f6359 100644 --- a/code/ryzom/server/src/shard_unifier_service/name_manager.cpp +++ b/code/ryzom/server/src/shard_unifier_service/name_manager.cpp @@ -1187,9 +1187,14 @@ bool CNameManager::loadForbiddenNames() while (true) { char str[512]; - fgets(str, 511, fp); + char *fgres = fgets(str, 511, fp); if(feof(fp)) break; + if (fgres == NULL) + { + nlwarning("NAMEMGR: Error reading file"); + break; + } if (strlen(str) > 0) { str[strlen(str)-1] = '\0'; diff --git a/code/ryzom/server/src/shard_unifier_service/ring_session_manager.cpp b/code/ryzom/server/src/shard_unifier_service/ring_session_manager.cpp index 987d4c86b..8d6c2a91f 100644 --- a/code/ryzom/server/src/shard_unifier_service/ring_session_manager.cpp +++ b/code/ryzom/server/src/shard_unifier_service/ring_session_manager.cpp @@ -208,7 +208,7 @@ namespace RSMGR public: CRingSessionManager() : _DontUsePerm(false), - _CharSync(false) + _CharSync(NULL) { CRingSessionManagerSkel::init(this); CWelcomeServiceClientSkel::init(this); diff --git a/code/ryzom/tools/client/client_config_qt/CMakeLists.txt b/code/ryzom/tools/client/client_config_qt/CMakeLists.txt index 87c5d7b05..82c1f6e3d 100644 --- a/code/ryzom/tools/client/client_config_qt/CMakeLists.txt +++ b/code/ryzom/tools/client/client_config_qt/CMakeLists.txt @@ -1,6 +1,5 @@ -INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ${QT_INCLUDES} ) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${NEL_INCLUDE_DIR} ${QT_INCLUDES}) +INCLUDE( ${QT_USE_FILE} ) FILE( GLOB SRC *.cpp *.h ) @@ -36,9 +35,6 @@ SET( CLIENT_CONFIG_TRANS CONFIGURE_FILE( translations/translations.qrc ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc COPYONLY ) SET( CLIENT_CONFIG_RCS resources.qrc ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc ) -SET( QT_USE_QTGUI TRUE ) -SET( QT_USE_QTOPENGL TRUE ) -SET( QT_USE_QTCORE TRUE ) QT4_ADD_TRANSLATION( CLIENT_CONFIG_QM ${CLIENT_CONFIG_TRANS} ) QT4_ADD_RESOURCES( CLIENT_CONFIG_RC_SRCS ${CLIENT_CONFIG_RCS} ) QT4_WRAP_CPP( CLIENT_CONFIG_MOC_SRC ${CLIENT_CONFIG_HDR} ) @@ -52,6 +48,11 @@ ADD_EXECUTABLE( ryzom_configuration_qt WIN32 MACOSX_BUNDLE ${SRC} ${CLIENT_CONFI NL_DEFAULT_PROPS( ryzom_configuration_qt "Ryzom, Tools: Ryzom Configuration Qt" ) NL_ADD_RUNTIME_FLAGS( ryzom_configuration_qt ) NL_ADD_LIB_SUFFIX( ryzom_configuration_qt ) -TARGET_LINK_LIBRARIES( ryzom_configuration_qt nelmisc nel3d ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${OPENGL_gl_LIBRARY} ) -INSTALL( TARGETS ryzom_configuration_qt RUNTIME DESTINATION games COMPONENT client BUNDLE DESTINATION /Applications ) +TARGET_LINK_LIBRARIES( ryzom_configuration_qt nelmisc nel3d ${QT_LIBRARIES} ${OPENGL_gl_LIBRARY}) + +IF(WITH_PCH) + ADD_NATIVE_PRECOMPILED_HEADER(ryzom_configuration_qt ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.h ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.cpp) +ENDIF(WITH_PCH) + +INSTALL(TARGETS ryzom_configuration_qt RUNTIME DESTINATION games COMPONENT client BUNDLE DESTINATION /Applications) diff --git a/code/ryzom/tools/client/client_config_qt/client_config_dialog.cpp b/code/ryzom/tools/client/client_config_qt/client_config_dialog.cpp index 5c6801152..df3596980 100644 --- a/code/ryzom/tools/client/client_config_qt/client_config_dialog.cpp +++ b/code/ryzom/tools/client/client_config_qt/client_config_dialog.cpp @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +#include "stdpch.h" #include "client_config_dialog.h" #include "general_settings_widget.h" diff --git a/code/ryzom/tools/client/client_config_qt/config.cpp b/code/ryzom/tools/client/client_config_qt/config.cpp index 93a757b27..55854862f 100644 --- a/code/ryzom/tools/client/client_config_qt/config.cpp +++ b/code/ryzom/tools/client/client_config_qt/config.cpp @@ -14,7 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -#include "Config.h" +#include "stdpch.h" +#include "config.h" CConfig::CConfig() { @@ -237,7 +238,7 @@ void CConfig::setFloat( const char *key, float value ) } } -void CConfig::setString( const char *key, std::string &value ) +void CConfig::setString( const char *key, const std::string &value ) { NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); @@ -252,4 +253,4 @@ void CConfig::setString( const char *key, std::string &value ) { nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); } -} \ No newline at end of file +} diff --git a/code/ryzom/tools/client/client_config_qt/config.h b/code/ryzom/tools/client/client_config_qt/config.h index df48e19e0..d9ddb536e 100644 --- a/code/ryzom/tools/client/client_config_qt/config.h +++ b/code/ryzom/tools/client/client_config_qt/config.h @@ -108,7 +108,7 @@ public: @param key - the key we want to alter @param value - the value we want to set */ - void setString( const char *key, std::string &value ); + void setString( const char *key, const std::string &value ); private: // config file diff --git a/code/ryzom/tools/client/client_config_qt/display_settings_advanced_widget.cpp b/code/ryzom/tools/client/client_config_qt/display_settings_advanced_widget.cpp index 211a4911b..0e0293555 100644 --- a/code/ryzom/tools/client/client_config_qt/display_settings_advanced_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/display_settings_advanced_widget.cpp @@ -14,7 +14,9 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +#include "stdpch.h" #include "display_settings_advanced_widget.h" + #include "system.h" CDisplaySettingsAdvancedWidget::CDisplaySettingsAdvancedWidget( QWidget *parent ) : diff --git a/code/ryzom/tools/client/client_config_qt/display_settings_details_widget.cpp b/code/ryzom/tools/client/client_config_qt/display_settings_details_widget.cpp index aeddcf628..74b48cc45 100644 --- a/code/ryzom/tools/client/client_config_qt/display_settings_details_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/display_settings_details_widget.cpp @@ -14,9 +14,11 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -#include "system.h" +#include "stdpch.h" #include "display_settings_details_widget.h" +#include "system.h" + CDisplaySettingsDetailsWidget::CDisplaySettingsDetailsWidget( QWidget *parent ) : CWidgetBase( parent ) { diff --git a/code/ryzom/tools/client/client_config_qt/display_settings_widget.cpp b/code/ryzom/tools/client/client_config_qt/display_settings_widget.cpp index 1771f23cf..d498d16af 100644 --- a/code/ryzom/tools/client/client_config_qt/display_settings_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/display_settings_widget.cpp @@ -14,9 +14,9 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -#include -#include +#include "stdpch.h" #include "display_settings_widget.h" + #include "system.h" #include @@ -30,6 +30,10 @@ CDisplaySettingsWidget::CDisplaySettingsWidget( QWidget *parent ) : ypositionLineEdit->setValidator( new QRegExpValidator( QRegExp( "[0-9]{1,6}" ), ypositionLineEdit ) ); load(); +#ifndef Q_OS_WIN32 + direct3dRadioButton->setEnabled(false); +#endif + connect( autoRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); connect( openglRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); connect( openGL3RB, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); @@ -78,7 +82,7 @@ void CDisplaySettingsWidget::load() CVideoMode mode; - mode.widht = s.config.getInt( "Width" ); + mode.width = s.config.getInt( "Width" ); mode.height = s.config.getInt( "Height" ); mode.depth = s.config.getInt( "Depth" ); mode.frequency = s.config.getInt( "Frequency" ); @@ -93,7 +97,7 @@ void CDisplaySettingsWidget::load() windowedRadioButton->setChecked( true ); } - widthLineEdit->setText( QString( "%1" ).arg( mode.widht ) ); + widthLineEdit->setText( QString( "%1" ).arg( mode.width ) ); heightLineEdit->setText( QString( "%1" ).arg( mode.height ) ); xpositionLineEdit->setText( QString( "%1" ).arg( s.config.getInt( "PositionX" ) ) ); ypositionLineEdit->setText( QString( "%1" ).arg( s.config.getInt( "PositionY" ) ) ); @@ -108,8 +112,11 @@ void CDisplaySettingsWidget::save() s.config.setString( "Driver3D", std::string( "OpenGL" ) ); else if( openGL3RB->isChecked() ) s.config.setString( "Driver3D", std::string( "OpenGL3" ) ); + +#ifdef Q_OS_WIN32 else if( direct3dRadioButton->isChecked() ) s.config.setString( "Driver3D", std::string( "Direct3D" ) ); +#endif else s.config.setString( "Driver3D", std::string( "Auto" ) ); @@ -121,12 +128,14 @@ void CDisplaySettingsWidget::save() CVideoMode mode; // OpenGL should be available everywhere! +#ifdef Q_OS_WIN32 if( direct3dRadioButton->isChecked() ) mode = s.d3dInfo.modes[ index ]; else +#endif mode = s.openglInfo.modes[ index ]; - s.config.setInt( "Width", mode.widht ); + s.config.setInt( "Width", mode.width ); s.config.setInt( "Height", mode.height ); s.config.setInt( "Depth", mode.depth ); s.config.setInt( "Frequency", mode.frequency ); @@ -160,24 +169,27 @@ void CDisplaySettingsWidget::updateVideoModes() videomodeComboBox->clear(); + std::vector< CVideoMode >::iterator itr, iend; + +#ifdef Q_OS_WIN32 if( direct3dRadioButton->isChecked() ) { - for( std::vector< CVideoMode >::iterator itr = s.d3dInfo.modes.begin(); itr != s.d3dInfo.modes.end(); ++itr ) - { - std::stringstream ss; - ss << itr->widht << "x" << itr->height << " " << itr->depth << " bit @" << itr->frequency; - videomodeComboBox->addItem( ss.str().c_str() ); - } + itr = s.d3dInfo.modes.begin(); + iend = s.d3dInfo.modes.end(); } else +#endif { // OpenGL should be available everywhere! - for( std::vector< CVideoMode >::iterator itr = s.openglInfo.modes.begin(); itr != s.openglInfo.modes.end(); ++itr ) - { - std::stringstream ss; - ss << itr->widht << "x" << itr->height << " " << itr->depth << " bit @" << itr->frequency; - videomodeComboBox->addItem( ss.str().c_str() ); - } + itr = s.openglInfo.modes.begin(); + iend = s.openglInfo.modes.end(); + } + + while(itr != iend) + { + videomodeComboBox->addItem(QString("%1x%2 %3 bit @%4").arg(itr->width).arg(itr->height).arg(itr->depth).arg(itr->frequency)); + + ++itr; } } @@ -201,6 +213,7 @@ uint32 CDisplaySettingsWidget::findVideoModeIndex( CVideoMode *mode ) CVideoMode &m = *mode; CSystem &s = CSystem::GetInstance(); +#ifdef Q_OS_WIN32 if( direct3dRadioButton->isChecked() ) { for( uint32 i = 0; i < s.d3dInfo.modes.size(); i++ ) @@ -208,6 +221,7 @@ uint32 CDisplaySettingsWidget::findVideoModeIndex( CVideoMode *mode ) return i; } else +#endif { // Again OpenGL should be available everywhere! for( uint32 i = 0; i < s.openglInfo.modes.size(); i++ ) diff --git a/code/ryzom/tools/client/client_config_qt/general_settings_widget.cpp b/code/ryzom/tools/client/client_config_qt/general_settings_widget.cpp index fcb85dec2..bb402b328 100644 --- a/code/ryzom/tools/client/client_config_qt/general_settings_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/general_settings_widget.cpp @@ -14,7 +14,9 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +#include "stdpch.h" #include "general_settings_widget.h" + #include "system.h" #include @@ -46,7 +48,7 @@ void CGeneralSettingsWidget::load() { CSystem &s = CSystem::GetInstance(); - sint32 cbIndex = getIndexForLanguageCode( QString( s.config.getString( "LanguageCode" ).c_str() ) ); + sint32 cbIndex = getIndexForLanguageCode( QString::fromUtf8( s.config.getString( "LanguageCode" ).c_str() ) ); if( cbIndex != -1 ){ languageComboBox->setCurrentIndex( cbIndex ); onLanguageChanged(); @@ -111,7 +113,7 @@ void CGeneralSettingsWidget::changeEvent( QEvent *event ) QWidget::changeEvent( event ); } -int CGeneralSettingsWidget::getIndexForLanguageCode( QString &languageCode ) +int CGeneralSettingsWidget::getIndexForLanguageCode(const QString &languageCode) { for( sint32 i = 0; i < NUM_LANGUAGE_CODES; i++ ) if( languageCode.compare( languageCodes[ i ] ) == 0 ) diff --git a/code/ryzom/tools/client/client_config_qt/general_settings_widget.h b/code/ryzom/tools/client/client_config_qt/general_settings_widget.h index c8d530ea5..412658a72 100644 --- a/code/ryzom/tools/client/client_config_qt/general_settings_widget.h +++ b/code/ryzom/tools/client/client_config_qt/general_settings_widget.h @@ -19,7 +19,6 @@ #include "ui_general_settings_widget.h" #include "widget_base.h" -#include class QTranslator; @@ -37,7 +36,7 @@ class CGeneralSettingsWidget : public CWidgetBase, public Ui::general_settings_w public: CGeneralSettingsWidget( QWidget *parent = NULL ); - ~CGeneralSettingsWidget(); + virtual ~CGeneralSettingsWidget(); void load(); void save(); @@ -54,7 +53,7 @@ private: @param languageCode - Reference to the language code, we are trying to find. @return Returns the index on success, returns -1 if the language code cannot be found. */ - sint32 getIndexForLanguageCode( QString &languageCode ); + sint32 getIndexForLanguageCode(const QString &languageCode); // Contains the language codes used in the config file // They are in the same order as the options in languageComboBox diff --git a/code/ryzom/tools/client/client_config_qt/main.cpp b/code/ryzom/tools/client/client_config_qt/main.cpp index 758598e92..0f41c508b 100644 --- a/code/ryzom/tools/client/client_config_qt/main.cpp +++ b/code/ryzom/tools/client/client_config_qt/main.cpp @@ -14,7 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -#include +#include "stdpch.h" + #include "client_config_dialog.h" #include "system.h" diff --git a/code/ryzom/tools/client/client_config_qt/sound_settings_widget.cpp b/code/ryzom/tools/client/client_config_qt/sound_settings_widget.cpp index 5436ac2b4..be637f8d8 100644 --- a/code/ryzom/tools/client/client_config_qt/sound_settings_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/sound_settings_widget.cpp @@ -14,7 +14,9 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +#include "stdpch.h" #include "sound_settings_widget.h" + #include "system.h" CSoundSettingsWidget::CSoundSettingsWidget( QWidget *parent ) : diff --git a/code/ryzom/tools/client/client_config_qt/sound_settings_widget.h b/code/ryzom/tools/client/client_config_qt/sound_settings_widget.h index d98a89d82..c995f1206 100644 --- a/code/ryzom/tools/client/client_config_qt/sound_settings_widget.h +++ b/code/ryzom/tools/client/client_config_qt/sound_settings_widget.h @@ -19,7 +19,6 @@ #include "ui_sound_settings_widget.h" #include "widget_base.h" -#include /** @brief The sound settings page of the configuration tool diff --git a/code/ryzom/tools/client/client_config_qt/stdpch.cpp b/code/ryzom/tools/client/client_config_qt/stdpch.cpp new file mode 100644 index 000000000..a3d45576c --- /dev/null +++ b/code/ryzom/tools/client/client_config_qt/stdpch.cpp @@ -0,0 +1,17 @@ +// Ryzom - MMORPG Framework +// 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 . + +#include "stdpch.h" diff --git a/code/nel/src/3d/driver/opengl3/driver_glsl_pixel_program.h b/code/ryzom/tools/client/client_config_qt/stdpch.h similarity index 69% rename from code/nel/src/3d/driver/opengl3/driver_glsl_pixel_program.h rename to code/ryzom/tools/client/client_config_qt/stdpch.h index cbea47ffd..6f6655761 100644 --- a/code/nel/src/3d/driver/opengl3/driver_glsl_pixel_program.h +++ b/code/ryzom/tools/client/client_config_qt/stdpch.h @@ -1,34 +1,29 @@ -// NeL - MMORPG Framework -// 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 . - - -#ifndef GLSL_PIXEL_PROGRAM_H -#define GLSL_PIXEL_PROGRAM_H - -#include "driver_glsl_program.h" - -namespace NL3D -{ - class CGLSLPixelProgram : public CGLSLProgram - { - public: - CGLSLPixelProgram(); - ~CGLSLPixelProgram(); - }; -} - -#endif - +// Ryzom - MMORPG Framework +// 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 . + +#ifndef STDPCH_H +#define STDPCH_H + +#include + +#include +#include + +#include +#include + +#endif + diff --git a/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.cpp b/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.cpp index 894ea07ac..140a75adc 100644 --- a/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.cpp @@ -14,7 +14,9 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +#include "stdpch.h" #include "sys_info_d3d_widget.h" + #include "system.h" CSysInfoD3DWidget::CSysInfoD3DWidget( QWidget *parent ) : @@ -22,9 +24,11 @@ CSysInfoD3DWidget::CSysInfoD3DWidget( QWidget *parent ) : { setupUi( this ); +#ifdef Q_OS_WIN32 descriptionLabel->setText( CSystem::GetInstance().d3dInfo.device.c_str() ); driverLabel->setText( CSystem::GetInstance().d3dInfo.driver.c_str() ); versionLabel->setText( CSystem::GetInstance().d3dInfo.driverVersion.c_str() ); +#endif } CSysInfoD3DWidget::~CSysInfoD3DWidget() diff --git a/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.h b/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.h index 6f79782ae..a77d89fa9 100644 --- a/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.h +++ b/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.h @@ -17,7 +17,7 @@ #ifndef SYSINFOD3DWIDGET_H #define SYSINFOD3DWIDGET_H -#include "ui_sys_Info_d3d_widget.h" +#include "ui_sys_info_d3d_widget.h" /** @@ -28,7 +28,7 @@ class CSysInfoD3DWidget : public QWidget, public Ui::sys_info_d3d_widget Q_OBJECT public: CSysInfoD3DWidget( QWidget *parent = NULL ); - ~CSysInfoD3DWidget(); + virtual ~CSysInfoD3DWidget(); protected: void changeEvent( QEvent *event ); diff --git a/code/ryzom/tools/client/client_config_qt/sys_info_opengl_widget.cpp b/code/ryzom/tools/client/client_config_qt/sys_info_opengl_widget.cpp index 0665025be..55deea24e 100644 --- a/code/ryzom/tools/client/client_config_qt/sys_info_opengl_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/sys_info_opengl_widget.cpp @@ -14,7 +14,9 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +#include "stdpch.h" #include "sys_info_opengl_widget.h" + #include "system.h" CSysInfoOpenGLWidget::CSysInfoOpenGLWidget( QWidget *parent ) : diff --git a/code/ryzom/tools/client/client_config_qt/sys_info_widget.cpp b/code/ryzom/tools/client/client_config_qt/sys_info_widget.cpp index 26d52ddb8..fcc0940dd 100644 --- a/code/ryzom/tools/client/client_config_qt/sys_info_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/sys_info_widget.cpp @@ -14,7 +14,9 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +#include "stdpch.h" #include "sys_info_widget.h" + #include "system.h" CSysInfoWidget::CSysInfoWidget( QWidget *parent ) : diff --git a/code/ryzom/tools/client/client_config_qt/system.cpp b/code/ryzom/tools/client/client_config_qt/system.cpp index c4c93f76d..6070e4abd 100644 --- a/code/ryzom/tools/client/client_config_qt/system.cpp +++ b/code/ryzom/tools/client/client_config_qt/system.cpp @@ -14,18 +14,17 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +#include "stdpch.h" #include "system.h" -#include + #include #include #include -CSystem *CSystem::instance = NULL; - CSystem::CSystem() { GatherSysInfo(); -#ifdef WIN32 +#ifdef Q_OS_WIN32 GatherD3DInfo(); #endif GatherOpenGLInfo(); @@ -33,9 +32,32 @@ CSystem::CSystem() CSystem::~CSystem() { - instance = 0; } +bool CSystem::parseDriverVersion(const std::string &device, uint64 driver, std::string &version) +{ + // file version + uint32 version1 = driver >> 48; + uint32 version2 = (driver >> 32) & 0xffff; + uint32 version3 = (driver >> 16) & 0xffff; + uint32 version4 = driver & 0xffff; + + if (device.find("NVIDIA") != std::string::npos) + { + // nvidia should be something like 9.18.13.2018 and 9.18.13.1422 + // which respectively corresponds to drivers 320.18 and 314.22 + uint32 nvVersionMajor = (version3 % 10) * 100 + (version4 / 100); + uint32 nvVersionMinor = version4 % 100; + + version = NLMISC::toString("%u.%u", nvVersionMajor, nvVersionMinor); + } + else + { + version = NLMISC::toString("%u.%u.%u.%u", version1, version2, version3, version4); + } + + return true; +} void CSystem::GatherSysInfo() { @@ -46,24 +68,7 @@ void CSystem::GatherSysInfo() { sysInfo.videoDevice = device; - ////////////////////////////////////////////////////////////// - // FIXME - // This is taken from the original configuration tool, and - // it generates the same *wrong* version number - ////////////////////////////////////////////////////////////// - uint32 version = static_cast< uint32 >( driver & 0xffff ); - std::stringstream ss; - - ss << ( version / 1000 % 10 ); - ss << "."; - ss << ( version / 100 % 10 ); - ss << "."; - ss << ( version / 10 % 10 ); - ss << "."; - ss << ( version % 10 ); - - sysInfo.videoDriverVersion = ss.str(); - ////////////////////////////////////////////////////////////// + CSystem::parseDriverVersion(device, driver, sysInfo.videoDriverVersion); } else { @@ -77,7 +82,7 @@ void CSystem::GatherSysInfo() sysInfo.totalRAM /= ( 1024 * 1024 ); } -#ifdef WIN32 +#ifdef Q_OS_WIN32 void CSystem::GatherD3DInfo() { NL3D::IDriver *driver = NULL; @@ -92,16 +97,7 @@ void CSystem::GatherD3DInfo() d3dInfo.device = adapter.Description; d3dInfo.driver = adapter.Driver; - sint64 ver = adapter.DriverVersion; - std::stringstream ss; - ss << static_cast< uint16 >( ver >> 48 ); - ss << "."; - ss << static_cast< uint16 >( ver >> 32 ); - ss << "."; - ss << static_cast< uint16 >( ver >> 16 ); - ss << "."; - ss << static_cast< uint16 >( ver & 0xFFFF ); - d3dInfo.driverVersion = ss.str(); + CSystem::parseDriverVersion(d3dInfo.device, adapter.DriverVersion, d3dInfo.driverVersion); } GetVideoModes( d3dInfo.modes, driver ); @@ -109,7 +105,7 @@ void CSystem::GatherD3DInfo() driver->release(); } - catch( NLMISC::Exception &e ) + catch(const NLMISC::Exception &e) { nlwarning( e.what() ); } @@ -146,15 +142,13 @@ void CSystem::GatherOpenGLInfo() delete gl; - NL3D::IDriver *driver = NULL; try { - driver = NL3D::CDRU::createGlDriver(); + NL3D::IDriver *driver = NL3D::CDRU::createGlDriver(); GetVideoModes( openglInfo.modes, driver ); driver->release(); } - - catch( NLMISC::Exception &e ) + catch(const NLMISC::Exception &e) { nlwarning( e.what() ); } @@ -171,11 +165,11 @@ void CSystem::GetVideoModes( std::vector< CVideoMode > &dst, NL3D::IDriver *driv { CVideoMode mode; mode.depth = itr->Depth; - mode.widht = itr->Width; + mode.width = itr->Width; mode.height = itr->Height; mode.frequency = itr->Frequency; dst.push_back( mode ); } } -} \ No newline at end of file +} diff --git a/code/ryzom/tools/client/client_config_qt/system.h b/code/ryzom/tools/client/client_config_qt/system.h index bcb5f90bf..1cc25a4bf 100644 --- a/code/ryzom/tools/client/client_config_qt/system.h +++ b/code/ryzom/tools/client/client_config_qt/system.h @@ -27,22 +27,22 @@ class IDriver; struct CVideoMode { - unsigned int widht; - unsigned int height; - unsigned int depth; - unsigned int frequency; + uint16 width; + uint16 height; + uint8 depth; + uint8 frequency; CVideoMode() { - widht = 0; + width = 0; height = 0; depth = 0; frequency = 0; } - bool operator==( CVideoMode &o ) + bool operator== (const CVideoMode &o) { - if( ( o.widht == widht ) && ( o.height == height ) && ( o.depth == depth ) && ( o.frequency == frequency ) ) + if ((o.width == width) && (o.height == height) && (o.depth == depth) && (o.frequency == frequency)) return true; else return false; @@ -60,11 +60,8 @@ public: static CSystem &GetInstance() { - if( instance == 0 ) - { - instance = new CSystem; - } - return *instance; + static CSystem sInstance; + return sInstance; } struct CSysInfo @@ -74,16 +71,18 @@ public: std::string osName; std::string cpuName; uint64 totalRAM; - } sysInfo; + } + sysInfo; -#ifdef WIN32 +#ifdef Q_OS_WIN32 struct CD3DInfo { std::string device; std::string driver; std::string driverVersion; std::vector< CVideoMode > modes; - } d3dInfo; + } + d3dInfo; #endif struct COpenGLInfo @@ -93,20 +92,22 @@ public: std::string driverVersion; std::string extensions; std::vector< CVideoMode > modes; - } openglInfo; + } + openglInfo; CConfig config; private: void GatherSysInfo(); -#ifdef WIN32 +#ifdef Q_OS_WIN32 void GatherD3DInfo(); #endif void GatherOpenGLInfo(); - void GetVideoModes( std::vector< CVideoMode > &dst, NL3D::IDriver *driver ) const; + void GetVideoModes(std::vector &dst, NL3D::IDriver *driver) const; - static CSystem *instance; + static bool parseDriverVersion(const std::string &device, uint64 driver, std::string &version); }; #endif // SYSTEM_H + diff --git a/code/ryzom/tools/leveldesign/georges_editor_qt/src/formitem.h b/code/ryzom/tools/leveldesign/georges_editor_qt/src/formitem.h index 18a0ae23e..3f4ad0c98 100644 --- a/code/ryzom/tools/leveldesign/georges_editor_qt/src/formitem.h +++ b/code/ryzom/tools/leveldesign/georges_editor_qt/src/formitem.h @@ -1,5 +1,5 @@ /* -Georges Editor Qt +Georges Editor Qt Copyright (C) 2010 Adrian Jaekel This program is free software: you can redistribute it and/or modify @@ -14,58 +14,58 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ - -#ifndef FORMITEM_H -#define FORMITEM_H - -// NeL includes -#include - -// Qt includes -#include -#include - -namespace NLQT -{ - - class CFormItem - - { - public: - CFormItem(NLGEORGES::UFormElm *elm, const QList &data, - CFormItem *parent = 0, - NLGEORGES::UFormElm::TWhereIsValue = NLGEORGES::UFormElm::ValueForm, - NLGEORGES::UFormElm::TWhereIsNode = NLGEORGES::UFormElm::NodeForm); - ~CFormItem(); - - void appendChild(CFormItem *child); - - CFormItem *child(int row); - int childCount() const; - int columnCount() const; - QVariant data(int column) const; - int row() const; - CFormItem *parent(); - bool setData(int column, const QVariant &value); - NLGEORGES::UFormElm* getFormElm() {return formElm;} - NLGEORGES::UFormElm::TWhereIsValue valueFrom() - { - return whereV; - } - NLGEORGES::UFormElm::TWhereIsNode nodeFrom() - { - return whereN; - } - - private: - QList childItems; - QList itemData; - CFormItem *parentItem; - NLGEORGES::UFormElm* formElm; - NLGEORGES::UFormElm::TWhereIsValue whereV; - NLGEORGES::UFormElm::TWhereIsNode whereN; - }; // CFormItem - -} -#endif // FORMITEM_H +*/ + +#ifndef FORMITEM_H +#define FORMITEM_H + +// NeL includes +#include + +// Qt includes +#include +#include + +namespace NLQT +{ + + class CFormItem + + { + public: + CFormItem(NLGEORGES::UFormElm *elm, const QList &data, + CFormItem *parent = 0, + NLGEORGES::UFormElm::TWhereIsValue = NLGEORGES::UFormElm::ValueForm, + NLGEORGES::UFormElm::TWhereIsNode = NLGEORGES::UFormElm::NodeForm); + ~CFormItem(); + + void appendChild(CFormItem *child); + + CFormItem *child(int row); + int childCount() const; + int columnCount() const; + QVariant data(int column) const; + int row() const; + CFormItem *parent(); + bool setData(int column, const QVariant &value); + NLGEORGES::UFormElm* getFormElm() {return formElm;} + NLGEORGES::UFormElm::TWhereIsValue valueFrom() + { + return whereV; + } + NLGEORGES::UFormElm::TWhereIsNode nodeFrom() + { + return whereN; + } + + private: + QList childItems; + QList itemData; + CFormItem *parentItem; + NLGEORGES::UFormElm* formElm; + NLGEORGES::UFormElm::TWhereIsValue whereV; + NLGEORGES::UFormElm::TWhereIsNode whereN; + }; // CFormItem + +} +#endif // FORMITEM_H diff --git a/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFades.cpp b/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFades.cpp index e0285a3fb..8b9092b4c 100644 --- a/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFades.cpp +++ b/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFades.cpp @@ -25,6 +25,7 @@ #include "nel/sound/u_audio_mixer.h" #include "PageBgFades.h" +#include "resource.h" using namespace std; diff --git a/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFlags.cpp b/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFlags.cpp index bc0d108f4..239c5b370 100644 --- a/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFlags.cpp +++ b/code/ryzom/tools/leveldesign/georges_plugin_sound/PageBgFlags.cpp @@ -25,6 +25,7 @@ #include "nel/sound/u_audio_mixer.h" #include "PageBgFlags.h" +#include "resource.h" using namespace std; diff --git a/code/ryzom/tools/leveldesign/georges_plugin_sound/PageComtext.cpp b/code/ryzom/tools/leveldesign/georges_plugin_sound/PageComtext.cpp index 46856b955..b3add5365 100644 --- a/code/ryzom/tools/leveldesign/georges_plugin_sound/PageComtext.cpp +++ b/code/ryzom/tools/leveldesign/georges_plugin_sound/PageComtext.cpp @@ -21,6 +21,7 @@ #include "georges_plugin_sound.h" #include #include "PageComtext.h" +#include "resource.h" using namespace std; diff --git a/code/ryzom/tools/leveldesign/georges_plugin_sound/std_sound_plugin.h b/code/ryzom/tools/leveldesign/georges_plugin_sound/std_sound_plugin.h index 3e5c33d17..9122d1f49 100644 --- a/code/ryzom/tools/leveldesign/georges_plugin_sound/std_sound_plugin.h +++ b/code/ryzom/tools/leveldesign/georges_plugin_sound/std_sound_plugin.h @@ -14,16 +14,18 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +#ifndef STDAFX_H +#define STDAFX_H + #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #define NOMINMAX #define _WIN32_WINNT 0x0500 #include // MFC core and standard components #include // MFC extensions -#include "resource.h" #include "nel/misc/types_nl.h" #include "nel/misc/debug.h" #include "nel/georges/u_form_elm.h" -#include "georges_plugin_sound.h" +#endif diff --git a/code/ryzom/tools/leveldesign/mission_compiler_lib/mission_compiler.cpp b/code/ryzom/tools/leveldesign/mission_compiler_lib/mission_compiler.cpp index 4fdd68869..5e54e5298 100644 --- a/code/ryzom/tools/leveldesign/mission_compiler_lib/mission_compiler.cpp +++ b/code/ryzom/tools/leveldesign/mission_compiler_lib/mission_compiler.cpp @@ -177,8 +177,8 @@ GenderExtractor::GenderExtractor(const std::string & literal, const std::string& static const char * es[] ={"e", "e1", "e2", "e3"}; - static char * fs[] ={"f", "f1", "f2", "f3"}; - static char * hs[] ={"h", "h1", "h2", "h3"}; + static const char * fs[] ={"f", "f1", "f2", "f3"}; + static const char * hs[] ={"h", "h1", "h2", "h3"}; const char * e = es[level]; const char * f = fs[level]; diff --git a/code/ryzom/tools/leveldesign/mission_compiler_lib/variables.cpp b/code/ryzom/tools/leveldesign/mission_compiler_lib/variables.cpp index 853d487ba..bf405ab5c 100644 --- a/code/ryzom/tools/leveldesign/mission_compiler_lib/variables.cpp +++ b/code/ryzom/tools/leveldesign/mission_compiler_lib/variables.cpp @@ -331,7 +331,7 @@ REGISTER_VAR_INDIRECT(CVarSBrick, "var_sbrick"); /* for special item */ -char *SpecialItemProp[] = +const char *SpecialItemProp[] = { "Durability", "Weight", diff --git a/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp b/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp index e7a1b2a33..a9d1daa9e 100644 --- a/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp +++ b/code/ryzom/tools/server/build_world_packed_col/build_world_packed_col.cpp @@ -276,7 +276,7 @@ int main(int argc, char* argv[]) try { CIFile f(builderConfig.CWMapCachePath + "/" + shortname + ".cw_height"); - f.serialCheck((uint32) 'OBSI'); + f.serialCheck(NELID("OBSI")); f.serial(xmin); f.serial(xmax); f.serial(ymin); @@ -322,7 +322,7 @@ int main(int argc, char* argv[]) // now extract each island height // read back coordinates CIFile f(builderConfig.CWMapCachePath + "/" + shortname + ".cw_height"); - f.serialCheck((uint32) 'OBSI'); + f.serialCheck(NELID("OBSI")); f.serial(xmin); f.serial(xmax); f.serial(ymin); @@ -349,7 +349,7 @@ int main(int argc, char* argv[]) try { COFile f(builderConfig.OutputPath + "/" + completeIslands[l]->Island + ".island_hm"); - f.serialCheck((uint32) 'MHSI'); + f.serialCheck(NELID("MHSI")); f.serial(island); // export tga for check if (builderConfig.HeightMapsAsTga) diff --git a/code/ryzom/tools/server/build_world_packed_col/packed_world_builder.cpp b/code/ryzom/tools/server/build_world_packed_col/packed_world_builder.cpp index d08982ae4..810540cf8 100644 --- a/code/ryzom/tools/server/build_world_packed_col/packed_world_builder.cpp +++ b/code/ryzom/tools/server/build_world_packed_col/packed_world_builder.cpp @@ -401,7 +401,7 @@ void CPackedWorldBuilder::fly(std::vector &islands, float camSpeed // fly into scene try { - CNELU::init(1024, 768, CViewport(), 32, true, NULL, false, true); + CNELU::init(1024, 768, CViewport(), 32, true, EmptyWindow, false, true); } catch(const Exception &e) { diff --git a/code/ryzom/tools/server/build_world_packed_col/test_col_world.cpp b/code/ryzom/tools/server/build_world_packed_col/test_col_world.cpp index 21f85b760..27e56403f 100644 --- a/code/ryzom/tools/server/build_world_packed_col/test_col_world.cpp +++ b/code/ryzom/tools/server/build_world_packed_col/test_col_world.cpp @@ -607,7 +607,7 @@ int main(int argc, char* argv[]) // fly into scene try { - CNELU::init(1024, 768, CViewport(), 32, true, NULL, false, true); + CNELU::init(1024, 768, CViewport(), 32, true, EmptyWindow, false, true); } catch(const Exception &e) { diff --git a/code/snowballs2/bin/pp_oculus_vr.cg b/code/snowballs2/bin/pp_oculus_vr.cg new file mode 100644 index 000000000..c7de282ef --- /dev/null +++ b/code/snowballs2/bin/pp_oculus_vr.cg @@ -0,0 +1,54 @@ +/************************************************************************************ + +Filename : pp_oculus_vr.cg +Content : Barrel fragment program ported from Oculus SDK Samples to Cg +Created : July 01, 2013 +Modified by : Jan Boon (Kaetemi) + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + + +void pp_oculus_vr( + // Per fragment parameters + float2 texCoord : TEXCOORD0, + + // Fragment program constants + uniform float2 cLensCenter, + uniform float2 cScreenCenter, + uniform float2 cScale, + uniform float2 cScaleIn, + uniform float4 cHmdWarpParam, + uniform sampler2D nlTex0 : TEX0, + + // Output color + out float4 oCol : COLOR) +{ + float2 theta = (texCoord - cLensCenter) * cScaleIn; // Scales to [-1, 1] + float rSq = theta.x * theta.x + theta.y * theta.y; + float2 theta1 = theta * (cHmdWarpParam.x + cHmdWarpParam.y * rSq + + cHmdWarpParam.z * rSq * rSq + cHmdWarpParam.w * rSq * rSq * rSq); + float2 tc = cLensCenter + cScale * theta1; + + if (!all(equal(clamp(tc, cScreenCenter-float2(0.25,0.5), cScreenCenter+float2(0.25,0.5)), tc))) + { + oCol = float4(0, 0, 0, 0); + } + else + { + oCol = tex2D(nlTex0, tc); + } +} diff --git a/code/snowballs2/bin/pp_stereo_debug.cg b/code/snowballs2/bin/pp_stereo_debug.cg new file mode 100644 index 000000000..3af27864d --- /dev/null +++ b/code/snowballs2/bin/pp_stereo_debug.cg @@ -0,0 +1,25 @@ + +void pp_stereo_debug( + // Per fragment parameters + float2 texCoord : TEXCOORD0, + + // Fragment program constants + uniform sampler2D cTex0 : TEX0, + uniform sampler2D cTex1 : TEX1, + + // Output color + out float4 oCol : COLOR) +{ + float4 t1 = tex2D(cTex0, texCoord); + float4 t2 = tex2D(cTex1, texCoord); + if (!any(t1 - t2)) + { + oCol = (t1 * 0.5) + (t2 * 0.5); + oCol.g = 0.5 + (oCol.g * 0.5); + } + else + { + oCol = (t1 * 0.5) + (t2 * 0.5); + oCol.r = 0.5 + (oCol.r * 0.5); + } +} diff --git a/code/snowballs2/bin/pp_test.cg b/code/snowballs2/bin/pp_test.cg new file mode 100644 index 000000000..f44c2d424 --- /dev/null +++ b/code/snowballs2/bin/pp_test.cg @@ -0,0 +1,13 @@ +void pp_test( + // Per fragment parameters + float2 texCoord : TEXCOORD0, + + // Fragment program constants + uniform sampler2D cTex0 : TEX0, + + // Output color + out float4 oCol : COLOR) +{ + oCol.rba = float3(1.0, 0.0, 1.0); + oCol.g = tex2D(cTex0, texCoord).g; +} \ No newline at end of file diff --git a/code/snowballs2/bin/snowballs_client_default.cfg b/code/snowballs2/bin/snowballs_client_default.cfg old mode 100644 new mode 100755 index 37b958820..49ec9e4d5 --- a/code/snowballs2/bin/snowballs_client_default.cfg +++ b/code/snowballs2/bin/snowballs_client_default.cfg @@ -47,17 +47,26 @@ FpsSmoothing = 64; OpenGL = 1; // Resolution of the screen -ScreenWidth = 800; -ScreenHeight = 600; +ScreenWidth = 1280; +ScreenHeight = 800; ScreenDepth = 32; // If 1, run in fullscreen mode, 0 for windowed -ScreenFull = 0; +ScreenFull = 1; // Start position of the player (the z is always 0) StartPoint = { 1840.0, -970.0, 0.0 }; +////////////////////////////////////////////////////////////////////////////// +// HMD Variables ///////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +HMDEnable = 1; +HMDDeviceId = 0; +HMDDevice = "Auto"; + + ////////////////////////////////////////////////////////////////////////////// // Sound Variables /////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -256,6 +265,15 @@ RetrieverBankName = "snowballs.rbank"; GlobalRetrieverName = "snowballs.gr"; +////////////////////////////////////////////////////////////////////////////// +// Bloom Variables /////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +SquareBloom = 1; +DensityBloom = 128; +EnableBloom = 1; + + ////////////////////////////////////////////////////////////////////////////// // Compass interface Variables /////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// diff --git a/code/snowballs2/client/src/animation.cpp b/code/snowballs2/client/src/animation.cpp index ab873ffbc..dd2296e25 100644 --- a/code/snowballs2/client/src/animation.cpp +++ b/code/snowballs2/client/src/animation.cpp @@ -97,7 +97,7 @@ Anim AnimIdArray[][2] = void computeAnimation (CEntity &entity, EAnim anim) { // Get the current time - double currentTime = double (CTime::getLocalTime ())/1000.0f; + double currentTime = AnimationTime; // nlinfo ("%d playing animation", anim); // nlinfo ("%d playing animation %s ct%f st%f et%f", anim, AnimIdArray[anim][0].Name, currentTime, AnimIdArray[anim][0].Animation->getBeginTime (), AnimIdArray[anim][0].Animation->getEndTime ()); @@ -153,7 +153,7 @@ void playAnimation (CEntity &entity, EAnim anim, bool force) // nlinfo ("playAnimation() %d", anim); // Get the current time - CAnimationTime currentTime = CAnimationTime(CTime::getLocalTime ())/1000.0f; + CAnimationTime currentTime = AnimationTime; // Can't do animation without skeleton if (entity.Skeleton.empty()) @@ -224,7 +224,7 @@ void initAnimation() void updateAnimation() { // Get the current time - CAnimationTime currentTime = CAnimationTime(CTime::getLocalTime ())/1000.0f; + CAnimationTime currentTime = AnimationTime; for (EIT eit = Entities.begin (); eit != Entities.end (); eit++) { @@ -270,7 +270,7 @@ void updateAnimation() } // compute new animation position depending of the current time - PlayListManager->animate (double(CTime::getLocalTime ())/1000.0f); + PlayListManager->animate (AnimationTime); } void releaseAnimation() diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index b202fba63..28ce273bb 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -33,6 +34,8 @@ #include #include +#include + #include "snowballs_client.h" #include "entities.h" #include "mouse_listener.h" @@ -61,22 +64,75 @@ UVisualCollisionEntity *CamCollisionEntity = NULL; static UInstance Snow = NULL; // The sky 3D objects -static UScene *SkyScene = NULL; -static UCamera SkyCamera = NULL; +UScene *SkyScene = NULL; +UCamera SkyCamera = NULL; static UInstance Sky = NULL; static UCloudScape *Clouds = NULL; +IStereoDisplay *StereoDisplay = NULL; +IStereoHMD *StereoHMD = NULL; + // // Functions // void initCamera() { + if (ConfigFile->getVar("HMDEnable").asBool()) + { + std::vector devices; + IStereoDisplay::listDevices(devices); + for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) + { + std::stringstream name; + name << std::string("[") << it->Serial << "] [" << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName << "]"; + nlinfo("Stereo Display: %s", name.str().c_str()); + } + CStereoDeviceInfo *deviceInfo = NULL; + std::string hmdDeviceCfg = ConfigFile->getVar("HMDDevice").asString(); + if (hmdDeviceCfg == std::string("Auto") + && devices.begin() != devices.end()) + { + deviceInfo = &devices[0]; + } + else + { + std::string hmdDeviceId = ConfigFile->getVar("HMDDeviceId").asString(); + for (std::vector::iterator it(devices.begin()), end(devices.end()); it != end; ++it) + { + std::stringstream name; + name << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName; + if (name.str() == hmdDeviceCfg) + deviceInfo = &(*it); + if (hmdDeviceId == it->Serial) + break; + } + } + if (deviceInfo) + { + nlinfo("Create VR stereo display device"); + StereoDisplay = IStereoDisplay::createDevice(*deviceInfo); + if (StereoDisplay) + { + if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD) + { + nlinfo("Stereo display device is a HMD"); + StereoHMD = static_cast(StereoDisplay); + StereoHMD->setScale(3.0f); // snowballs is about 4 units per meter + } + StereoDisplay->setDriver(Driver); // move after driver creation, move stereodisplay before driver creation + } + } + } + IStereoDisplay::releaseUnusedLibraries(); + // Set up directly the camera Camera = Scene->getCam(); Camera.setTransformMode (UTransformable::DirectMatrix); - Camera.setPerspective ((float)Pi/2.f, 1.33f, 0.1f, 1000); + Camera.setPerspective((float)Pi/2.f, + ConfigFile->getVar("ScreenWidth").asFloat() / ConfigFile->getVar("ScreenHeight").asFloat(), + 0.1f, 1000.f); Camera.lookAt (CVector(ConfigFile->getVar("StartPoint").asFloat(0), ConfigFile->getVar("StartPoint").asFloat(1), ConfigFile->getVar("StartPoint").asFloat(2)), @@ -114,10 +170,30 @@ void releaseCamera() Driver->deleteScene(SkyScene); Scene->deleteInstance(Snow); VisualCollisionManager->deleteEntity(CamCollisionEntity); + + if (StereoHMD) + { + delete StereoHMD; + StereoHMD = NULL; + StereoDisplay = NULL; + } + delete StereoDisplay; + StereoDisplay = NULL; + IStereoDisplay::releaseAllLibraries(); } void updateCamera() { + if (StereoHMD) + { + NLMISC::CQuat hmdOrient = StereoHMD->getOrientation(); + NLMISC::CMatrix camMatrix = Camera.getMatrix(); + NLMISC::CMatrix hmdMatrix; + hmdMatrix.setRot(hmdOrient); + NLMISC::CMatrix posMatrix; // minimal head modeling, will be changed in the future + posMatrix.translate(StereoHMD->getEyePosition()); + Camera.setMatrix((camMatrix * hmdMatrix) * posMatrix); + } // Set the new position of the snow emitter CMatrix mat = CMatrix::Identity; mat.setPos (Camera.getMatrix().getPos()/*+CVector (0.0f, 0.0f, -10.0f)*/); @@ -143,7 +219,8 @@ void releaseSky() // -- -- random note: update and render makes more sense than animate and update void animateSky(double dt) { - Clouds->anim(dt); + if (!StereoHMD) Clouds->anim(dt); + SkyScene->animate(AnimationTime); } // this is actually render @@ -156,12 +233,12 @@ void updateSky() skyCameraMatrix.setPos(CVector::Null); SkyCamera.setMatrix(skyCameraMatrix); - SkyScene->animate(AnimationTime); SkyScene->render(); // Must clear ZBuffer For incoming rendering. Driver->clearZBuffer(); - Clouds->render(); + if (!StereoHMD) // Cloudscape not supported (fix Viewport please) + Clouds->render(); } } /* namespace SBCLIENT */ diff --git a/code/snowballs2/client/src/camera.h b/code/snowballs2/client/src/camera.h index c7718c653..c2d61d866 100644 --- a/code/snowballs2/client/src/camera.h +++ b/code/snowballs2/client/src/camera.h @@ -30,6 +30,7 @@ namespace NL3D { class UVisualCollisionEntity; + class CStereoOVR; }; namespace SBCLIENT { @@ -39,7 +40,9 @@ namespace SBCLIENT { // extern NL3D::UCamera Camera; +extern NL3D::UCamera SkyCamera; extern NL3D::UVisualCollisionEntity *CamCollisionEntity; +extern NL3D::UScene *SkyScene; // // External functions diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index 70dd3b247..41faeab1e 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -35,11 +35,20 @@ #include #include #include +#include #include "network.h" #include "snowballs_client.h" #include "interface.h" +#if SBCLIENT_DEV_PIXEL_PROGRAM +#include +#include +#include +#include +#include +#endif + // // Namespaces // @@ -237,6 +246,13 @@ void cbUpdateCommands (CConfigFile::CVar &var) else nlwarning ("Unknown variable update %s", var.Name.c_str()); } +#if SBCLIENT_DEV_PIXEL_PROGRAM +namespace { +CPixelProgram *a_DevPixelProgram = NULL; +UTextureFile *a_NelLogo; +} +#endif + void initCommands() { // Add the keyboard listener in the event server @@ -278,6 +294,79 @@ void initCommands() CommandsMaterial.initUnlit(); CommandsMaterial.setBlendFunc(UMaterial::srcalpha, UMaterial::invsrcalpha); CommandsMaterial.setBlend(true); + +#if SBCLIENT_DEV_PIXEL_PROGRAM + CommandsMaterial.getObjectPtr()->setShader(NL3D::CMaterial::PostProcessing); + a_NelLogo = Driver->createTextureFile("nel128.tga"); + CommandsMaterial.setTexture(dynamic_cast(a_NelLogo)); + static const char *program_arbfp1 = + "!!ARBfp1.0\n" + "PARAM c[1] = { { 1, 0 } };\n" + "MOV result.color.xzw, c[0].xyyx;\n" + "TEX result.color.y, fragment.texcoord[0], texture[0], 2D;\n" + "END\n"; + static const char *program_fp40 = + "!!ARBfp1.0\n" + "OPTION NV_fragment_program2;\n" + "PARAM c[1] = { { 1, 0 } };\n" + "TEMP RC;\n" + "TEMP HC;\n" + "OUTPUT oCol = result.color;\n" + "MOVR oCol.xzw, c[0].xyyx;\n" + "TEX oCol.y, fragment.texcoord[0], texture[0], 2D;\n" + "END\n"; + static const char *program_ps_1_1 = + "ps.1.1\n" + "def c0, 0.000000, 0.000000, 1.000000, 0.000000\n" + "def c1, 1.000000, 0.000000, 0.000000, 0.000000\n" + "def c2, 0.000000, 1.000000, 0.000000, 0.000000\n" + "tex t0\n" + "mad r0.rgb, c2, t0, c1\n" + "mov r0.a, c0.b\n"; + static const char *program_ps_2_0 = + "ps_2_0\n" + "dcl_2d s0\n" + "def c0, 1.00000000, 0.00000000, 0, 0\n" + "dcl t0.xy\n" + "texld r0, t0, s0\n" + "mov r0.z, c0.y\n" + "mov r0.xw, c0.x\n" + "mov oC0, r0\n"; + static const char *program_ps_3_0 = + "ps_3_0\n" + "dcl_2d s0\n" + "def c0, 1.00000000, 0.00000000, 0, 0\n" + "dcl_texcoord0 v0.xy\n" + "mov oC0.xzw, c0.xyyx\n" + "texld oC0.y, v0, s0\n"; + NL3D::IDriver *d = dynamic_cast(Driver)->getDriver(); + if (d->supportPixelProgram(CPixelProgram::fp40)) + { + nldebug("fp40"); + a_DevPixelProgram = new CPixelProgram(program_fp40); + } + else if (d->supportPixelProgram(CPixelProgram::arbfp1)) + { + nldebug("arbfp1"); + a_DevPixelProgram = new CPixelProgram(program_arbfp1); + } + /*else if (d->supportPixelProgram(CPixelProgram::ps_3_0)) + { + nldebug("ps_3_0"); + a_DevPixelProgram = new CPixelProgram(program_ps_3_0); + // Textures do not seem to work with ps_3_0... + }*/ + else if (d->supportPixelProgram(CPixelProgram::ps_2_0)) + { + nldebug("ps_2_0"); + a_DevPixelProgram = new CPixelProgram(program_ps_2_0); + } + else if (d->supportPixelProgram(CPixelProgram::ps_1_1)) + { + nldebug("ps_1_1"); + a_DevPixelProgram = new CPixelProgram(program_ps_1_1); + } +#endif } void updateCommands() @@ -286,6 +375,9 @@ void updateCommands() uint32 _width, _height; Driver->getWindowSize(_width, _height); float width = (float)_width, height = (float)_height; + NL3D::CViewport vp = Driver->getViewport(); + width *= vp.getWidth(); + height *= vp.getHeight(); float CommandsLineHeight = CommandsFontSize / height; float CommandsBoxX = ((float)(sint32)(SBCLIENT::CommandsBoxX * width)) / width; float CommandsBoxWidth = ((float)(sint32)(SBCLIENT::CommandsBoxWidth * width)) / width; @@ -293,16 +385,57 @@ void updateCommands() float CommandsBoxHeight = ((float)(sint32)((CommandsNbLines + 1) * CommandsLineHeight * width)) / width; float CommandsBoxBorderX = ((float)(sint32)(SBCLIENT::CommandsBoxBorder * width)) / width; float CommandsBoxBorderY = ((float)(sint32)(SBCLIENT::CommandsBoxBorder * height)) / height; + if (StereoHMD) + { + float xshift, yshift; + StereoHMD->getInterface2DShift(0, xshift, yshift, 4.f); + // snap to pixels + xshift = ((float)(sint32)(xshift * width)) / width; + yshift = ((float)(sint32)(yshift * height)) / height; + // adjust + CommandsBoxX += xshift; + CommandsBoxY += yshift; + } // Display the background Driver->setMatrixMode2D11 (); +#if SBCLIENT_DEV_PIXEL_PROGRAM + CommandsMaterial.setColor(CRGBA::Blue); // Test to check which shader is displaying. +#else CommandsMaterial.setColor(CommandsBackColor); +#endif float x0 = CommandsBoxX - CommandsBoxBorderX; float y0 = CommandsBoxY - CommandsBoxBorderY; float x1 = CommandsBoxX + CommandsBoxWidth + CommandsBoxBorderX; float y1 = CommandsBoxY + CommandsBoxHeight + CommandsBoxBorderY; + +#if SBCLIENT_DEV_PIXEL_PROGRAM + NL3D::IDriver *d = dynamic_cast(Driver)->getDriver(); + d->activePixelProgram(a_DevPixelProgram); + bool fogEnabled = d->fogEnabled(); + d->enableFog(false); + + // Driver->drawQuad(CQuad(CVector(x0, y0, 0), CVector(x1, y0, 0), CVector(x1, y1, 0), CVector(x0, y1, 0)), CommandsMaterial); + CQuadUV quadUV; + quadUV.V0 = CVector(x0, y0, 0); + quadUV.V1 = CVector(x1, y0, 0); + quadUV.V2 = CVector(x1, y1, 0); + quadUV.V3 = CVector(x0, y1, 0); + quadUV.Uv0 = CUV(0, 1); + quadUV.Uv1 = CUV(1, 1); + quadUV.Uv2 = CUV(1, 0); + quadUV.Uv3 = CUV(0, 0); + Driver->drawQuad(quadUV, CommandsMaterial); + //Driver->drawBitmap(x0, y0, x1 - x0, y1 - y0, *a_NelLogo); + + d->enableFog(fogEnabled); + d->activePixelProgram(NULL); +#else + Driver->drawQuad(CQuad(CVector(x0, y0, 0), CVector(x1, y0, 0), CVector(x1, y1, 0), CVector(x0, y1, 0)), CommandsMaterial); +#endif + // Set the text context TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setColor (CommandsFrontColor); @@ -334,6 +467,10 @@ void clearCommands () void releaseCommands() { +#if SBCLIENT_DEV_PIXEL_PROGRAM + delete a_DevPixelProgram; + a_DevPixelProgram = NULL; +#endif // Remove the displayers CommandsLog.removeDisplayer(&CommandsDisplayer); #ifndef NL_RELEASE diff --git a/code/snowballs2/client/src/compass.cpp b/code/snowballs2/client/src/compass.cpp index 11d7ddefa..27e0e27f1 100644 --- a/code/snowballs2/client/src/compass.cpp +++ b/code/snowballs2/client/src/compass.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "mouse_listener.h" #include "camera.h" @@ -94,6 +95,13 @@ void updateCompass () { float x = CompassPosX; float y = CompassPosY; + if (StereoHMD) + { + float xshift, yshift; + StereoHMD->getInterface2DShift(0, xshift, yshift, 4.f); + x += xshift; + y += yshift; + } float radius = CompassRadius; // tri @@ -109,7 +117,8 @@ void updateCompass () quad.V2.set ( radius, radius, 0); quad.V3.set (-radius, radius, 0); - Driver->setMatrixMode2D43 (); + if (StereoHMD) Driver->setMatrixMode2D11(); + else Driver->setMatrixMode2D43(); CMatrix mtx; @@ -152,7 +161,7 @@ void updateCompass () Driver->setModelMatrix (mtx); Driver->drawQuad (quad, CompassMaterial); - x *= 3.0/4.0f; + if (!StereoHMD) x *= 3.0/4.0f; // Print position TextContext->setHotSpot(UTextContext::MiddleTop); diff --git a/code/snowballs2/client/src/entities.cpp b/code/snowballs2/client/src/entities.cpp index af879958c..2972aebf1 100644 --- a/code/snowballs2/client/src/entities.cpp +++ b/code/snowballs2/client/src/entities.cpp @@ -105,7 +105,7 @@ bool _TestCLS = false; void CEntity::setState (TState state) { State = state; - StateStartTime = CTime::getLocalTime (); + StateStartTime = LocalTime; } @@ -376,7 +376,7 @@ void deleteAllEntities() void stateAppear (CEntity &entity) { // after 1 second, show the instance - if (CTime::getLocalTime () > entity.StateStartTime + 1000) + if (LocalTime > entity.StateStartTime + 1.0) { if (entity.Instance.getVisibility () != UTransform::Show) entity.Instance.show (); @@ -384,7 +384,7 @@ void stateAppear (CEntity &entity) // after 5 seconds, delete the particle system (if any) // and pass the entity into the Normal state - if (CTime::getLocalTime () > entity.StateStartTime + 3000) + if (LocalTime > entity.StateStartTime + 3.0) { if (!entity.Particule.empty()) { @@ -403,7 +403,7 @@ void stateAppear (CEntity &entity) void stateDisappear (CEntity &entity) { // after 1 second, remove the mesh and all collision stuff - if (CTime::getLocalTime () > entity.StateStartTime + 1000) + if (LocalTime > entity.StateStartTime + 1.0) { if (entity.Instance.getVisibility () != UTransform::Hide) { @@ -419,7 +419,7 @@ void stateDisappear (CEntity &entity) } // after 5 seconds, remove the particle system and the entity entry - if (CTime::getLocalTime () > entity.StateStartTime + 3000) + if (LocalTime > entity.StateStartTime + 3.0) { deleteEntity (entity); } diff --git a/code/snowballs2/client/src/entities.h b/code/snowballs2/client/src/entities.h index 0ad7819ee..e85ffc569 100644 --- a/code/snowballs2/client/src/entities.h +++ b/code/snowballs2/client/src/entities.h @@ -108,7 +108,7 @@ public: // The state of this entity TState State; // The date of the beginning of this state - NLMISC::TTime StateStartTime; + NLMISC::TLocalTime StateStartTime; // The type enum of the entity enum TType { Self, Other, Snowball }; diff --git a/code/snowballs2/client/src/game_time.cpp b/code/snowballs2/client/src/game_time.cpp index 62bfc2b2b..c6b1ff62c 100644 --- a/code/snowballs2/client/src/game_time.cpp +++ b/code/snowballs2/client/src/game_time.cpp @@ -42,6 +42,14 @@ static bool _SkipAnimationOnce; static NLMISC::TTime _TimeMs; static CValueSmootherTemplate _FpsSmoother; +namespace +{ + +NLMISC::TLocalTime a_LocalTimeDelta; +NL3D::TGlobalAnimationTime a_AnimationTimeDelta; + +} /* anonymous namespace */ + static void cbFpsSmoothing(CConfigFile::CVar &var) { _FpsSmoother.init((uint)var.asInt()); @@ -53,8 +61,10 @@ void CGameTime::init() _TimeMs = NLMISC::CTime::getLocalTime(); LocalTime = ((TLocalTime)_TimeMs) / 1000.0; LocalTimeDelta = 0.0; + a_LocalTimeDelta = 0.0; AnimationTime = 0.0; AnimationTimeDelta = 0.f; + a_AnimationTimeDelta = 0.0; FramesPerSecond = 0.f; FramesPerSecondSmooth = 0.f; CConfiguration::setAndCallback("FpsSmoothing", cbFpsSmoothing); @@ -78,26 +88,24 @@ void CGameTime::updateTime() // average of previous fps and this fps should be ok FramesPerSecond *= 3; - LocalTimeDelta = 0.f; - AnimationTimeDelta = 0.f; + a_LocalTimeDelta = 0.f; + a_AnimationTimeDelta = 0.f; } else { FramesPerSecond = 1000.0f / (float)deltams; TLocalTime localTime = ((TLocalTime)timems) / 1000.0; - LocalTimeDelta = localTime - LocalTime; - LocalTime = localTime; + a_LocalTimeDelta = localTime - LocalTime; if (_SkipAnimationOnce) { - AnimationTimeDelta = 0.f; + a_AnimationTimeDelta = 0.f; _SkipAnimationOnce = false; } else { - AnimationTimeDelta = (TAnimationTime)LocalTimeDelta; - AnimationTime += (TGlobalAnimationTime)LocalTimeDelta; + a_AnimationTimeDelta = (TGlobalAnimationTime)a_LocalTimeDelta; } } @@ -105,6 +113,15 @@ void CGameTime::updateTime() FramesPerSecondSmooth = _FpsSmoother.getSmoothValue(); } +void CGameTime::advanceTime(double f) +{ + LocalTimeDelta = a_LocalTimeDelta * f; + LocalTime += LocalTimeDelta; + TGlobalAnimationTime atd = a_AnimationTimeDelta * f; + AnimationTimeDelta = (NL3D::TAnimationTime)atd; + AnimationTime += atd; +} + void CGameTime::skipAnimationOnce() { _SkipAnimationOnce = true; diff --git a/code/snowballs2/client/src/game_time.h b/code/snowballs2/client/src/game_time.h index 72a671d43..7cf4ec827 100644 --- a/code/snowballs2/client/src/game_time.h +++ b/code/snowballs2/client/src/game_time.h @@ -40,6 +40,9 @@ public: static void updateTime(); + /// Advance time to target time by factor f. + static void advanceTime(double f); + /// Used when loading, this will skip changing animation time on the next update /// (updates aren't called during loading) static void skipAnimationOnce(); diff --git a/code/snowballs2/client/src/graph.cpp b/code/snowballs2/client/src/graph.cpp index 73ac726f5..8fd3dd85c 100644 --- a/code/snowballs2/client/src/graph.cpp +++ b/code/snowballs2/client/src/graph.cpp @@ -115,7 +115,7 @@ void CGraph::addValue (float value) // CGraph FpsGraph ("fps", 10.0f, 10.0f, 100.0f, 100.0f, CRGBA(128,0,0,128), 1000, 40.0f); -CGraph SpfGraph ("spf", 10.0f, 110.0f, 100.0f, 100.0f, CRGBA(0,128,0,128), 0, 200.0f); +CGraph SpfGraph ("spf", 10.0f, 110.0f, 100.0f, 100.0f, CRGBA(0,128,0,128), 0, 0.1f); CGraph DownloadGraph ("download", 10.0f, 260.0f, 100.0f, 100.0f, CRGBA(0,0,128,128), 1000, 1000.0f); CGraph UploadGraph ("upload", 10.0f, 360.0f, 100.0f, 100.0f, CRGBA(0,128,128,128), 1000, 1000.0f); diff --git a/code/snowballs2/client/src/mouse_listener.cpp b/code/snowballs2/client/src/mouse_listener.cpp index c459f6bd2..67508e281 100644 --- a/code/snowballs2/client/src/mouse_listener.cpp +++ b/code/snowballs2/client/src/mouse_listener.cpp @@ -427,6 +427,11 @@ void C3dMouseListener::updateCamera() cpos = snapped+CVector(0.0f, 0.0f, GroundCamLimit); _ViewHeight = cpos.z - getPosition().z; } + if (StereoHMD) + { + // look at straight forward + tpos.z = cpos.z; + } _Camera.lookAt(cpos, tpos); } diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index c5cb73072..b401d80bc 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -51,6 +51,7 @@ #if SBCLIENT_DEV_STEREO # include #endif /* #if SBCLIENT_DEV_STEREO */ +#include // Project includes #include "pacs.h" @@ -151,6 +152,8 @@ LoadedOnline = false, LoadedOffline = false; // state static IStereoRender *_StereoRender = NULL; #endif /* #if SBCLIENT_DEV_STEREO */ +static bool s_EnableBloom = false; + // // Prototypes // @@ -179,6 +182,9 @@ void releaseIngame(); void releaseOnline(); void releaseOffline(); void cbGraphicsDriver(CConfigFile::CVar &var); +void cbSquareBloom(CConfigFile::CVar &var); +void cbDensityBloom(CConfigFile::CVar &var); +void cbEnableBloom(CConfigFile::CVar &var); // // Functions @@ -306,11 +312,16 @@ void initCore() Driver->setDisplay(UDriver::CMode(ConfigFile->getVar("ScreenWidth").asInt(), ConfigFile->getVar("ScreenHeight").asInt(), ConfigFile->getVar("ScreenDepth").asInt(), - ConfigFile->getVar("ScreenFull").asInt()==0)); + (ConfigFile->getVar("OpenGL").asInt() == 1 ? true : ConfigFile->getVar("ScreenFull").asInt()==0))); // Set the cache size for the font manager(in bytes) Driver->setFontManagerMaxMemory(2097152); // Create a Text context for later text rendering displayLoadingState("Initialize Text"); + if (ConfigFile->getVar("OpenGL").asInt() == 1) + Driver->setMode(UDriver::CMode(ConfigFile->getVar("ScreenWidth").asInt(), + ConfigFile->getVar("ScreenHeight").asInt(), + ConfigFile->getVar("ScreenDepth").asInt(), + ConfigFile->getVar("ScreenFull").asInt()==0)); TextContext = Driver->createTextContext(CPath::lookup(ConfigFile->getVar("FontName").asString())); TextContext->setShaded(true); TextContext->setKeep800x600Ratio(false); @@ -354,6 +365,7 @@ void initIngame() //#ifdef NL_OS_WINDOWS // playMusic(SBCLIENT_MUSIC_WAIT); //#endif + displayLoadingState("Initialize"); // Create a scene Scene = Driver->createScene(false); @@ -362,7 +374,9 @@ void initIngame() CBloomEffect::instance().setDriver(Driver); CBloomEffect::instance().setScene(Scene); CBloomEffect::instance().init(ConfigFile->getVar("OpenGL").asInt() == 1); - + CConfiguration::setAndCallback("SquareBloom", cbSquareBloom); + CConfiguration::setAndCallback("DensityBloom", cbDensityBloom); + CConfiguration::setAndCallback("EnableBloom", cbEnableBloom); // Init the landscape using the previously created UScene displayLoadingState("Initialize Landscape"); initLandscape(); @@ -562,6 +576,8 @@ void releaseIngame() MouseListener = NULL; // release bloom effect + CConfiguration::dropCallback("SquareBloom"); + CConfiguration::dropCallback("DensityBloom"); CBloomEffect::instance().releaseInstance(); Driver->deleteScene(Scene); @@ -673,15 +689,16 @@ void loopIngame() // 02. Update Time (deltas) CGameTime::updateTime(); + CGameTime::advanceTime(1.0); - // 03. Update Input (keyboard controls, etc) + // 03. Update Incoming (network, receive messages) + updateNetwork(); + + // 04. Update Input (keyboard controls, etc) Driver->EventServer.pump(); // Pump user input messages MouseListener->update(); MouseListener->updateCamera(); - // 04. Update Incoming (network, receive messages) - updateNetwork(); - // 05. Update Weather (sky, snow, wind, fog, sun) animateSky(LocalTimeDelta); @@ -689,7 +706,7 @@ void loopIngame() updateLandscape(); // Update the landscape // ... Update Animations (TEST) - // ... + updateAnimation(); // 07. Update Entities (collisions and actions) // - Move Other Entities (move//, animations, etc) @@ -702,6 +719,7 @@ void loopIngame() // 09. Update Camera (depends on entities) updateCamera(); + if (StereoHMD) StereoHMD->updateCamera(0, &Camera); // 10. Update Interface (login, ui, etc) // ... @@ -721,52 +739,98 @@ void loopIngame() if (Driver->isLost()) nlSleep(10); else { - // call all 3d render thingies - Driver->clearBuffers(CRGBA(127, 0, 0)); // if you see red, there's a problem with bloom or stereo render -#if SBCLIENT_DEV_STEREO - _StereoRender->calculateCameras(Camera.getObjectPtr()); // calculate modified matrices for the current camera - for (uint cameraId = 0; cameraId < _StereoRender->getCameraCount(); ++cameraId) + uint i = 0; + uint bloomStage = 0; + while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass())) { - _StereoRender->getCamera(cameraId, Camera.getObjectPtr()); // get the matrix details for this camera -#endif /* #if SBCLIENT_DEV_STEREO */ + ++i; + if (StereoDisplay) + { + const CViewport &vp = StereoDisplay->getCurrentViewport(); + Driver->setViewport(vp); + Scene->setViewport(vp); + SkyScene->setViewport(vp); + StereoDisplay->getCurrentFrustum(0, &Camera); + StereoDisplay->getCurrentFrustum(0, &SkyCamera); + StereoDisplay->getCurrentMatrix(0, &Camera); + } - // 01. Render Driver (background color) - CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) - Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering + if (StereoDisplay) + { + StereoDisplay->beginRenderTarget(); + } + + if (!StereoDisplay || StereoDisplay->wantClear()) + { - // 02. Render Sky (sky scene) - updateSky(); // Render the sky scene before the main scene + if (s_EnableBloom) + { + nlassert(bloomStage == 0); + CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) + bloomStage = 1; + } - // 04. Render Scene (entity scene) - Scene->render(); // Render + // 01. Render Driver (background color) + Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering + } - // 05. Render Effects (flare) - updateLensFlare(); // Render the lens flare - CBloomEffect::instance().endBloom(); // end the actual bloom effect visible in the scene + if (!StereoDisplay || StereoDisplay->wantScene()) + { + // 02. Render Sky (sky scene) + updateSky(); // Render the sky scene before the main scene - // 06. Render Interface 3D (player names) - CBloomEffect::instance().endInterfacesDisplayBloom(); // end bloom effect system after drawing the 3d interface (z buffer related) + // 04. Render Scene (entity scene) + Scene->render(); // Render -#if SBCLIENT_DEV_STEREO - _StereoRender->copyBufferToTexture(cameraId); // copy current buffer to the active stereorender texture - } - _StereoRender->restoreCamera(Camera.getObjectPtr()); // restore the camera - _StereoRender->render(); // render everything together in the current mode -#endif /* #if SBCLIENT_DEV_STEREO */ + // 05. Render Effects (flare) + if (!StereoHMD) updateLensFlare(); // Render the lens flare (left eye stretched with stereo...) + } - // 07. Render Interface 2D (chatboxes etc, optionally does have 3d) - updateCompass(); // Update the compass - updateRadar(); // Update the radar - updateGraph(); // Update the radar - if (ShowCommands) updateCommands(); // Update the commands panel - updateAnimation(); - renderEntitiesNames(); // Render the name on top of the other players - updateInterface(); // Update interface - renderInformation(); - update3dLogo(); + if (!StereoDisplay || StereoDisplay->wantInterface3D()) + { + if (s_EnableBloom && bloomStage == 1) + { + // End the actual bloom effect visible in the scene. + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); + CBloomEffect::instance().endBloom(); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); + bloomStage = 2; + } + + // 06. Render Interface 3D (player names) + // ... + } + + if (!StereoDisplay || StereoDisplay->wantInterface2D()) + { + if (s_EnableBloom && bloomStage == 2) + { + // End bloom effect system after drawing the 3d interface (z buffer related). + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); + CBloomEffect::instance().endInterfacesDisplayBloom(); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); + bloomStage = 0; + } + + // 07. Render Interface 2D (chatboxes etc, optionally does have 3d) + updateCompass(); // Update the compass + updateRadar(); // Update the radar + updateGraph(); // Update the radar + if (ShowCommands) updateCommands(); // Update the commands panel + renderEntitiesNames(); // Render the name on top of the other players + updateInterface(); // Update interface + renderInformation(); + if (!StereoDisplay) update3dLogo(); // broken with stereo + + // 08. Render Debug (stuff for dev) + // ... + } - // 08. Render Debug (stuff for dev) - // ... + if (StereoDisplay) + { + StereoDisplay->endRenderTarget(); + } + } // 09. Render Buffer Driver->swapBuffers(); @@ -868,6 +932,8 @@ void renderInformation() TextContext->setColor(CRGBA(255, 255, 255, 255)); TextContext->setFontSize(14); TextContext->printfAt(0.01f, 0.99f, "%.2f(%.2f)fps %.3fs", FramesPerSecondSmooth, FramesPerSecond, (float)LocalTimeDelta); + CVector camPos = Camera.getMatrix().getPos(); + TextContext->printfAt(0.01f, 0.89f, "CAM POS: %.3f %.3f %.3f", camPos.x, camPos.y, camPos.z); // one more frame FpsGraph.addValue(1.0f); @@ -884,6 +950,21 @@ void cbGraphicsDriver(CConfigFile::CVar &var) NextGameState = GameStateReset; } +void cbSquareBloom(CConfigFile::CVar &var) +{ + CBloomEffect::instance().setSquareBloom(var.asBool()); +} + +void cbDensityBloom(CConfigFile::CVar &var) +{ + CBloomEffect::instance().setDensityBloom((uint8)(var.asInt() & 0xFF)); +} + +void cbEnableBloom(CConfigFile::CVar &var) +{ + s_EnableBloom = var.asBool(); +} + // // Loading state procedure // @@ -1124,21 +1205,29 @@ sint main(int argc, char **argv) FILE *f = _tfopen(_T(SBCLIENT_CONFIG_FILE_DEFAULT), _T("r")); if (!f) { - OutputDebugString(" ******************************** \n"); - OutputDebugString(" * CHANGING WORKING DIRECTORY * \n"); - OutputDebugString(" ******************************** \n\n"); - char cwd[256]; - _tgetcwd(cwd, 256); - tstring workdir(cwd); - workdir += "\\..\\bin\\"; - _tchdir(workdir.c_str()); - f = _tfopen(_T(SBCLIENT_CONFIG_FILE_DEFAULT), _T("r")); + f = _tfopen(_T(SBCLIENT_CONFIG_FILE), _T("r")); if (!f) { OutputDebugString(" ******************************** \n"); - OutputDebugString(" * DEFAULT CONFIG MISSING * \n"); + OutputDebugString(" * CHANGING WORKING DIRECTORY * \n"); OutputDebugString(" ******************************** \n\n"); - return EXIT_FAILURE; + char cwd[256]; + _tgetcwd(cwd, 256); + tstring workdir(cwd); + workdir = "R:\\build\\devw_x86\\bin\\Debug\\"; + _tchdir(workdir.c_str()); + f = _tfopen(_T(SBCLIENT_CONFIG_FILE_DEFAULT), _T("r")); + if (!f) + { + f = _tfopen(_T(SBCLIENT_CONFIG_FILE), _T("r")); + if (!f) + { + OutputDebugString(" ******************************** \n"); + OutputDebugString(" * DEFAULT CONFIG MISSING * \n"); + OutputDebugString(" ******************************** \n\n"); + return EXIT_FAILURE; + } + } } } fclose(f); diff --git a/code/snowballs2/client/src/snowballs_client.h b/code/snowballs2/client/src/snowballs_client.h index 67116f7e6..d21f925f7 100644 --- a/code/snowballs2/client/src/snowballs_client.h +++ b/code/snowballs2/client/src/snowballs_client.h @@ -42,6 +42,8 @@ namespace NL3D { class UScene; class UTextContext; class ULandscape; + class IStereoDisplay; + class IStereoHMD; } namespace SBCLIENT { @@ -58,6 +60,8 @@ public: }; extern NL3D::UDriver *Driver; +extern NL3D::IStereoDisplay *StereoDisplay; +extern NL3D::IStereoHMD *StereoHMD; extern NL3D::UScene *Scene; extern NL3D::UTextContext *TextContext; extern NLMISC::CConfigFile *ConfigFile; diff --git a/code/snowballs2/client/src/snowballs_config.h b/code/snowballs2/client/src/snowballs_config.h index edd282718..2e6b848fb 100644 --- a/code/snowballs2/client/src/snowballs_config.h +++ b/code/snowballs2/client/src/snowballs_config.h @@ -37,7 +37,11 @@ #define SBCLIENT_ERASE_LOG true // version number -#define SBCLIENT_VERSION "2.1.551" +// 2.1 +// - Bloom +// 2.2 +// - OculusVR support +#define SBCLIENT_VERSION "2.2" @@ -45,6 +49,7 @@ #define SBCLIENT_DEV_SOUND 0 #define SBCLIENT_DEV_STEREO 0 #define SBCLIENT_DEV_MEMLEAK 0 +#define SBCLIENT_DEV_PIXEL_PROGRAM 0 @@ -70,7 +75,7 @@ # ifndef SNOWBALLS_CONFIG # define SBCLIENT_CONFIG_FILE "snowballs_client.cfg" # else -# define SBCLIENT_CONFIG_FILE SNOWBALLS_CONFIG "client.cfg" +# define SBCLIENT_CONFIG_FILE SNOWBALLS_CONFIG "snowballs_client.cfg" # endif #endif