Merged the GPU program stuff from mainline.

--HG--
branch : gsoc2013-dfighter
hg/feature/gsoc2013-dfighter
dfighter1985 11 years ago
commit 982b99d8d0

@ -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)

@ -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)

@ -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)

@ -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)

@ -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 <lua/lua.h>
# 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)

@ -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)

@ -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)

@ -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)

@ -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")

@ -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")

@ -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)

@ -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})

@ -138,6 +138,8 @@ private:
NLMISC::CSmartPtr<NL3D::ITexture> _BlurFinalTex;
// used as render target in first blur pass, and as displayed texture on second blur pass.
NLMISC::CSmartPtr<NL3D::ITexture> _BlurHorizontalTex;
// original render target
NLMISC::CSmartPtr<NL3D::ITexture> _OriginalRenderTarget;
// materials

File diff suppressed because it is too large Load Diff

@ -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);
// @}

@ -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 <nel/misc/types_nl.h>
#include <nel/misc/smart_ptr.h>
#include <nel/3d/program.h>
#include <list>
namespace NL3D {
class CGeometryProgram : public IProgram
{
public:
/// Constructor
CGeometryProgram();
/// Destructor
virtual ~CGeometryProgram ();
};
} // NL3D
#endif // NL_GEOMETRY_PROGRAM_H
/* End of vertex_program.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
* <http://www.gnu.org/licenses/>.
*/
#ifndef NL3D_GPU_PROGRAM_PARAMS_H
#define NL3D_GPU_PROGRAM_PARAMS_H
#include <nel/misc/types_nl.h>
// STL includes
#include <map>
#include <vector>
// 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<CVec> m_Vec;
std::vector<CMeta> m_Meta;
std::vector<size_t> m_Map; // map from index to offset
std::map<std::string, size_t> 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 */

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

@ -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<CVertexProgramLandscape> _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

@ -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 <memory>
@ -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.
// @{

@ -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<CVertexProgram> _VertexProgram[NumVp];
static NLMISC::CSmartPtr<CVertexProgramPerPixelLight> _VertexProgram[NumVp];
NLMISC::CRefPtr<CVertexProgramPerPixelLight> _ActiveVertexProgram;
};
} // NL3D

@ -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<CVertexProgram> _VertexProgram[NumVp];
static NLMISC::CSmartPtr<CVertexProgramWindTree> _VertexProgram[NumVp];
NLMISC::CRefPtr<CVertexProgramWindTree> _ActiveVertexProgram;
// WindTree Time for this mesh param setup. Stored in mesh because same for all instances.
float _CurrentTime[HrcDepth];

@ -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 <nel/misc/types_nl.h>
#include <nel/misc/smart_ptr.h>
#include <nel/3d/program.h>
#include <list>
namespace NL3D {
class CPixelProgram : public IProgram
{
public:
/// Constructor
CPixelProgram();
/// Destructor
virtual ~CPixelProgram ();
};
} // NL3D
#endif // NL_PIXEL_PROGRAM_H
/* End of vertex_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
* <http://www.gnu.org/licenses/>.
*/
#ifndef NL3D_PROGRAM_H
#define NL3D_PROGRAM_H
#include <nel/misc/types_nl.h>
// STL includes
// NeL includes
#include <nel/misc/smart_ptr.h>
// Project includes
namespace NL3D {
// List typedef.
class IDriver;
class IProgramDrvInfos;
typedef std::list<IProgramDrvInfos*> 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<std::string, uint> 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<NLMISC::CSmartPtr<CSource> > m_Sources;
/// The source used for compilation
NLMISC::CSmartPtr<CSource> m_Source;
CProgramIndex m_Index;
public:
/// The driver information. For the driver implementation only.
NLMISC::CRefPtr<IProgramDrvInfos> m_DrvInfo;
}; /* class IProgram */
} /* namespace NL3D */
#endif /* #ifndef NL3D_PROGRAM_H */
/* end of file */

@ -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 <vector>
@ -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<CVertexProgramLighted> _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.

@ -826,7 +826,8 @@ private:
void flushSSSModelRequests();
// common vb for water display
CVertexBuffer _WaterVB;
bool _RequestParticlesAnimate;
};

@ -1,99 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_SHADER_H
#define NL_SHADER_H
#include "nel/misc/types_nl.h"
#include "nel/misc/smart_ptr.h"
#include <list>
namespace NL3D {
using NLMISC::CRefCount;
class IDriver;
// List typedef.
class IShaderDrvInfos;
typedef std::list<IShaderDrvInfos*> 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<IShaderDrvInfos> _DrvInfo;
private:
// The shader
std::string _Text;
// The shader name
std::string _Name;
};
} // NL3D
#endif // NL_SHADER_H
/* End of shader.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
* <http://www.gnu.org/licenses/>.
*/
#if !FINAL_VERSION
#ifndef NL3D_STEREO_DEBUGGER_H
#define NL3D_STEREO_DEBUGGER_H
#include <nel/misc/types_nl.h>
// STL includes
// NeL includes
#include <nel/misc/smart_ptr.h>
#include <nel/misc/geom_ext.h>
// Project includes
#include <nel/3d/stereo_display.h>
#include <nel/3d/frustum.h>
#include <nel/3d/viewport.h>
#include <nel/3d/u_material.h>
#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<CStereoDeviceInfo> &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<NL3D::ITexture> m_LeftTex;
NL3D::CTextureUser *m_LeftTexU;
NLMISC::CSmartPtr<NL3D::ITexture> 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 */

@ -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
* <http://www.gnu.org/licenses/>.
*/
#ifndef NL3D_STEREO_DISPLAY_H
#define NL3D_STEREO_DISPLAY_H
#include <nel/misc/types_nl.h>
// STL includes
// NeL includes
#include <nel/misc/smart_ptr.h>
// 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<IStereoDeviceFactory> 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<CStereoDeviceInfo> &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 */

@ -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
* <http://www.gnu.org/licenses/>.
*/
#ifndef NL3D_STEREO_HMD_H
#define NL3D_STEREO_HMD_H
#include <nel/misc/types_nl.h>
// STL includes
// NeL includes
// Project includes
#include <nel/3d/stereo_display.h>
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 */

@ -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
* <http://www.gnu.org/licenses/>.
*/
#ifndef NL3D_STEREO_LIBVR_H
#define NL3D_STEREO_LIBVR_H
#ifdef HAVE_LIBVR
#include <nel/misc/types_nl.h>
// STL includes
// NeL includes
#include <nel/misc/smart_ptr.h>
#include <nel/misc/geom_ext.h>
// Project includes
#include <nel/3d/stereo_hmd.h>
#include <nel/3d/frustum.h>
#include <nel/3d/viewport.h>
#include <nel/3d/u_material.h>
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<CStereoDeviceInfo> &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<NL3D::ITexture> 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 */

@ -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
* <http://www.gnu.org/licenses/>.
*
* 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 <nel/misc/types_nl.h>
// STL includes
// NeL includes
#include <nel/misc/smart_ptr.h>
#include <nel/misc/geom_ext.h>
// Project includes
#include <nel/3d/stereo_hmd.h>
#include <nel/3d/frustum.h>
#include <nel/3d/viewport.h>
#include <nel/3d/u_material.h>
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<CStereoDeviceInfo> &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<NL3D::ITexture> m_BarrelTex;
NL3D::CTextureUser *m_BarrelTexU;
NL3D::UMaterial m_BarrelMat;
NLMISC::CQuadUV m_BarrelQuadLeft;
NLMISC::CQuadUV m_BarrelQuadRight;
NLMISC::CRefPtr<CPixelProgramOVR> 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 */

@ -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.

@ -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<CVertexProgramVeget> _VertexProgram[NL3D_VEGETABLE_NRDRPASS][2];
CRefPtr<CVertexProgramVeget> _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.

@ -19,90 +19,24 @@
#include "nel/misc/types_nl.h"
#include "nel/misc/smart_ptr.h"
#include "nel/3d/program.h"
#include <list>
namespace NL3D {
// List typedef.
class IDriver;
class IVertexProgramDrvInfos;
typedef std::list<IVertexProgramDrvInfos*> 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<IVertexProgramDrvInfos> _DrvInfo;
};
} // NL3D

@ -21,6 +21,40 @@
#include <vector>
/**
* 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

@ -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; }

@ -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<CVertexProgram> _VertexProgramBump1;
static std::auto_ptr<CVertexProgram> _VertexProgramBump2;
/*static NLMISC::CSmartPtr<CVertexProgram> _VertexProgramBump1;
static NLMISC::CSmartPtr<CVertexProgram> _VertexProgramBump2;
//
static std::auto_ptr<CVertexProgram> _VertexProgramBump1Diffuse;
static std::auto_ptr<CVertexProgram> _VertexProgramBump2Diffuse;
static NLMISC::CSmartPtr<CVertexProgram> _VertexProgramBump1Diffuse;
static NLMISC::CSmartPtr<CVertexProgram> _VertexProgramBump2Diffuse;
//
static std::auto_ptr<CVertexProgram> _VertexProgramNoBump;
static std::auto_ptr<CVertexProgram> _VertexProgramNoBumpDiffuse;
static NLMISC::CSmartPtr<CVertexProgram> _VertexProgramNoBump;
static NLMISC::CSmartPtr<CVertexProgram> _VertexProgramNoBumpDiffuse;*/
//
static std::auto_ptr<CVertexProgram> _VertexProgramNoWave;
static std::auto_ptr<CVertexProgram> _VertexProgramNoWaveDiffuse;
static NLMISC::CSmartPtr<CVertexProgramWaterVPNoWave> _VertexProgramNoWave;
static NLMISC::CSmartPtr<CVertexProgramWaterVPNoWave> _VertexProgramNoWaveDiffuse;
};

@ -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;

@ -19,6 +19,7 @@
#include "types_nl.h"
#include <cmath>
#include <nel/misc/debug.h>
namespace NLMISC
{

@ -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.

@ -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)

@ -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);

@ -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);

@ -55,13 +55,18 @@ static const char *TextureOffset =
END \n";
static CVertexProgram TextureOffsetVertexProgram(TextureOffset);
static NLMISC::CSmartPtr<CVertexProgram> 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<CDriverUser *>(_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<CDriverUser *>(_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<CDriverUser *>(_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<CDriverUser *>(_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<CDriverUser *>(_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

@ -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;

@ -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);
}
// ***************************************************************************

@ -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);
}

@ -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<IShaderDrvInfos*> 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<IShaderDrvInfos> _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<std::string, uint>::const_iterator it = ParamIndices.find(name);
if (it != ParamIndices.end()) return it->second;
return ~0;
};
std::map<std::string, uint> 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<std::string, uint>::const_iterator it = ParamIndices.find(name);
if (it != ParamIndices.end()) return it->second;
return ~0;
};
std::map<std::string, uint> 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<float> &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 &params); // 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<CVertexProgram> _VertexProgramUser;
NLMISC::CRefPtr<CPixelProgram> _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))

@ -328,7 +328,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat)
pShader = static_cast<CMaterialDrvInfosD3D*>((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 ; stage<maxTexture; ++stage)
@ -668,7 +670,9 @@ bool CDriverD3D::setupMaterial(CMaterial &mat)
// Don't do it also for Specular because the EnvFunction and the TexGen may be special.
{
H_AUTO_D3D(CDriverD3D_setupMaterial_normalShaderActivateTextures)
if(matShader == CMaterial::Normal)
if (matShader == CMaterial::Normal
|| ((matShader == CMaterial::Program) && (_PixelProgramUser->features().MaterialFlags & CProgramFeatures::TextureStages))
)
{
uint stage;
for(stage=0 ; stage<maxTexture; ++stage)
@ -933,7 +937,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat)
activeShader (NULL);
/* If unlighted trick is needed, set the shader later */
if (!pShader->NeedsConstantForDiffuse && _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;
}
// ***************************************************************************

@ -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<CPixelProgramDrvInfosD3D *>((IProgramDrvInfos*)program->m_DrvInfo);
_PixelProgramUser = program;
setPixelShader(info->Shader);
}
else
{
setPixelShader(NULL);
_PixelProgramUser = NULL;
}
return true;
}
// ***************************************************************************
void CDriverD3D::disableHardwarePixelProgram()
{
H_AUTO_D3D(CDriverD3D_disableHardwarePixelProgram)
_DisableHardwarePixelProgram = true;
_PixelProgram = false;
}
} // NL3D

@ -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<uint8> 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<CShaderDrvInfosD3D*>((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)

@ -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 */,

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

@ -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<CVertexProgamDrvInfosD3D *>((IVertexProgramDrvInfos*)program->_DrvInfo);
if (!CDriverD3D::compileVertexProgram(program)) return false;
CVertexProgamDrvInfosD3D *info = NLMISC::safe_cast<CVertexProgamDrvInfosD3D *>((IProgramDrvInfos*)program->m_DrvInfo);
_VertexProgramUser = program;
setVertexProgram (info->Shader, program);
/* D3DRS_FOGSTART and D3DRS_FOGEND must be set with [1, 0] else the fog doesn't work properly on VertexShader and non-VertexShader objects
(random fog flicking) with Geforce4 TI 4200 (drivers 53.03 and 45.23). The other cards seam to interpret the "oFog"'s values using D3DRS_FOGSTART,
D3DRS_FOGEND.
Related to setUniformFog().
*/
float z = 0;
float o = 1;
@ -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<num; i++)
setVertexProgramConstant (index+i, src+i*4);
}
// ***************************************************************************
void CDriverD3D::setConstant (uint index, uint num, const double *src)
{
H_AUTO_D3D(CDriverD3D_setConstant )
if (!_VertexProgram)
{
#ifdef NL_DEBUG
nlwarning("No vertex programs available!!");
#endif
return;
}
uint i;
for (i=0; i<num; i++)
{
const float tabl[4] = {(float)src[0], (float)src[1], (float)src[2], (float)src[3]};
setVertexProgramConstant (index+i, tabl);
src += 4;
}
}
// ***************************************************************************
void CDriverD3D::setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform)
{
H_AUTO_D3D(CDriverD3D_setConstantMatrix )
if (!_VertexProgram)
{
#ifdef NL_DEBUG
nlwarning("No vertex programs available!!");
#endif
return;
}
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)
{
mat = *matPtr;
matPtr = &mat;
switch(transform)
{
case IDriver::Inverse:
D3DXMatrixInverse (&mat, NULL, &mat);
break;
case IDriver::Transpose:
D3DXMatrixTranspose (&mat, &mat);
break;
case IDriver::InverseTranspose:
D3DXMatrixInverse (&mat, NULL, &mat);
D3DXMatrixTranspose (&mat, &mat);
break;
}
}
setConstant (index, matPtr->_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)

@ -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)
{

@ -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<ITexture> _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<CVertexProgram> _LastSetuppedVP;
// The last pixel program that was setupped
NLMISC::CRefPtr<CPixelProgram> _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<std::string, uint>::const_iterator it = ParamIndices.find(name);
if (it != ParamIndices.end()) return it->second;
return ~0;
};
std::map<std::string, uint> 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<std::string, uint>::const_iterator it = ParamIndices.find(name);
if (it != ParamIndices.end()) return it->second;
return ~0;
};
std::map<std::string, uint> ParamIndices;
};
#ifdef NL_STATIC

@ -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.

@ -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 " : "";

@ -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 ; stage<inlGetNumTextStages() ; stage++)
for (uint stage = 0; stage < inlGetNumTextStages(); ++stage)
{
ITexture *text= mat.getTexture(uint8(stage));
if (text != NULL && !setupTexture(*text))
@ -394,7 +417,7 @@ bool CDriverGL::setupMaterial(CMaterial& mat)
// Here, for Lightmap materials, setup the lightmaps.
if(matShader == CMaterial::LightMap)
{
for(stage = 0; stage < mat._LightMaps.size(); stage++)
for (uint stage = 0; stage < mat._LightMaps.size(); ++stage)
{
ITexture *text = mat._LightMaps[stage].Texture;
if (text != NULL && !setupTexture(*text))
@ -418,9 +441,10 @@ bool CDriverGL::setupMaterial(CMaterial& mat)
&& matShader != CMaterial::Cloud
&& matShader != CMaterial::Water
&& matShader != CMaterial::Specular
&& ((matShader != CMaterial::Program) || (_LastSetuppedPP->features().MaterialFlags & CProgramFeatures::TextureStages))
)
{
for(stage=0 ; stage<inlGetNumTextStages() ; stage++)
for(uint stage=0 ; stage<inlGetNumTextStages() ; stage++)
{
ITexture *text= mat.getTexture(uint8(stage));
@ -548,11 +572,13 @@ bool CDriverGL::setupMaterial(CMaterial& mat)
resetLightMapVertexSetup();
// Textures user matrix
if (matShader == CMaterial::Normal)
if (matShader == CMaterial::Normal
|| ((matShader == CMaterial::Program) && (_LastSetuppedPP->features().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)

@ -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 <algorithm>
// 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<CPixelProgamDrvInfosGL*>((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<CPixelProgamDrvInfosGL *>((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

@ -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,

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

@ -1151,7 +1151,7 @@ void CDriverGL::toggleGlArraysForEXTVertexShader()
CVertexProgram *vp = _LastSetuppedVP;
if (vp)
{
CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IVertexProgramDrvInfos *) vp->_DrvInfo);
CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((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<CVertexProgamDrvInfosGL *>((IVertexProgramDrvInfos *) vp->_DrvInfo);
CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IProgramDrvInfos *) vp->m_DrvInfo);
if (!drvInfo) return;
uint32 flags= vb.VertexFormat;

@ -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<length)&&(offset<(uint)errorOff))
{
if (sString[offset]=='\n')
{
line++;
charC=1;
}
else
charC++;
#else
// Next character
offset++;
}
return false;
// Show the error
nlwarning("3D: Vertex program syntax error line %d character %d\n", line, charC);
#endif
}
// Disable vertex program
glDisable (GL_VERTEX_PROGRAM_NV);
_VertexProgramEnabled= false;
// ***************************************************************************
bool CDriverGL::activeNVVertexProgram(CVertexProgram *program)
{
H_AUTO_OGL(CVertexProgamDrvInfosGL_activeNVVertexProgram);
// Setup not ok
return false;
}
#ifndef USE_OPENGLES
// Setup or unsetup ?
if (program)
{
// Driver info
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IProgramDrvInfos*)program->m_DrvInfo);
nlassert(drvInfo);
// Setup ok
return true;
}
else
{
// Cast the driver info pointer
drvInfo=safe_cast<CVertexProgamDrvInfosGL*>((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<CVertexProgamDrvInfosGL*>((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<CVertexProgamDrvInfosGL*>((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<CVertexProgamDrvInfosGL*>((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<CVertexProgamDrvInfosGL*>((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;
}
// ***************************************************************************

@ -23,6 +23,7 @@
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <X11/XKBlib.h>
#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

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

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

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

@ -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;

@ -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)
{

@ -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<GfxMode> &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<CVertexProgram> _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

@ -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 ] );
}
{

@ -15,9 +15,6 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#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 ] );
}
}

@ -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

@ -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;

@ -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<CVertexBuffer &>(mesh.getVertexBuffer()));
// query drawn count

@ -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 <nel/3d/geometry_program.h>
#include <nel/3d/driver.h>
namespace NL3D
{
// ***************************************************************************
CGeometryProgram::CGeometryProgram()
{
}
// ***************************************************************************
CGeometryProgram::~CGeometryProgram ()
{
}
// ***************************************************************************
} // NL3D

@ -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
* <http://www.gnu.org/licenses/>.
*/
#include <nel/misc/types_nl.h>
#include <nel/3d/gpu_program_params.h>
// STL includes
// NeL includes
// #include <nel/misc/debug.h>
#include <nel/misc/vector.h>
#include <nel/misc/matrix.h>
// Project includes
#include <nel/3d/driver.h>
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<std::string, size_t>::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 */

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

@ -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);
}
}
}

@ -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;i<MaxVertexProgram;i++)
for (uint i = 0; i < MaxVertexProgram; ++i)
{
if(_VertexProgram[i])
if (_VertexProgram[i])
{
delete _VertexProgram[i];
_VertexProgram[i]= NULL;
_VertexProgram[i] = NULL; // smartptr
}
}
}
@ -560,9 +571,8 @@ void CLandscapeVBAllocator::setupVBFormatAndVertexProgram(bool withVertexProgr
_VB.initEx();
// Init the Vertex Program.
string vpgram= string(NL3D_LandscapeCommonStartProgram) +
string(NL3D_LandscapeFar0EndProgram);
_VertexProgram[0]= new CVertexProgram(vpgram.c_str());
_VertexProgram[0] = new CVertexProgramLandscape(Far0);
nlverify(_Driver->compileVertexProgram(_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

@ -264,9 +264,9 @@ void CLodCharacterShapeBuild::compile(const std::vector<bool> &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:

@ -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"

@ -32,14 +32,13 @@
namespace NL3D
{
std::auto_ptr<CVertexProgram> CMeshVPPerPixelLight::_VertexProgram[NumVp];
NLMISC::CSmartPtr<CVertexProgramPerPixelLight> 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<CVertexProgram>(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;
}
//=================================================================================

@ -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<CVertexProgram> CMeshVPWindTree::_VertexProgram[CMeshVPWindTree::NumVp];
NLMISC::CSmartPtr<CVertexProgramWindTree> 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<NumVp;i++)
{
@ -153,13 +226,16 @@ void CMeshVPWindTree::initInstance(CMeshBaseInstance *mbi)
bool normalize= (i&1)!=0;
bool specular= (i&2)!=0;
// combine fragments
vpCode= string(WindTreeVPCodeWave)
+ CRenderTrav::getLightVPFragment(numPls, VPLightConstantStart, specular, normalize)
+ WindTreeVPCodeEnd;
_VertexProgram[i]= std::auto_ptr<CVertexProgram>(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;
}
// ***************************************************************************

@ -152,7 +152,7 @@ void CPackedWorld::getZones(std::vector<TPackedZoneBaseSPtr> &zones)
void CPackedWorld::serialZoneNames(NLMISC::IStream &f) throw(NLMISC::EStream)
{
f.serialVersion(1);
f.serialCheck((uint32) 'OWPA');
f.serialCheck(NELID("OWPA"));
f.serialCont(ZoneNames);
}

@ -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 <nel/3d/pixel_program.h>
#include <nel/3d/driver.h>
namespace NL3D
{
// ***************************************************************************
CPixelProgram::CPixelProgram()
{
}
// ***************************************************************************
CPixelProgram::~CPixelProgram ()
{
}
// ***************************************************************************
} // NL3D

@ -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
* <http://www.gnu.org/licenses/>.
*/
#include <nel/misc/types_nl.h>
#include <nel/3d/program.h>
// STL includes
// NeL includes
// #include <nel/misc/debug.h>
#include <nel/misc/string_mapper.h>
// Project includes
#include <nel/3d/driver.h>
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 */

@ -73,7 +73,7 @@ CPSLocated::CPSLocated() : /*_MaxNumFaces(0),*/
_ParametricMotion(false),
_TriggerOnDeath(false),
_LastForever(true),
_TriggerID((uint32) 'NONE'),
_TriggerID(NELID("NONE")),
_NonIntegrableForceNbRefs(0),
_NumIntegrableForceWithDifferentBasis(0)
{

@ -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<CTextureBump *>((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<CTextureBump *>((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<NLMISC::CSmartPtr<ITexture>
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

@ -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(; i<MaxVPLight; i++)
{
_VPLightDiffuse[i]= CRGBA::Black;
Driver->setConstant(_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(; i<MaxVPLight; i++)
{
_VPLightSpecular[i]= CRGBA::Black;
Driver->setConstant(_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;

@ -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();

@ -405,7 +405,7 @@ void CInstanceGroup::serial (NLMISC::IStream& f)
* ***********************************************/
// Serial a header
f.serialCheck ((uint32)'TPRG');
f.serialCheck (NELID("TPRG"));
/*
Version 5:

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

@ -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<NL3D::ITexture> 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);

@ -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);

@ -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);

@ -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
* <http://www.gnu.org/licenses/>.
*/
#if !FINAL_VERSION
#include <nel/misc/types_nl.h>
#include <nel/3d/stereo_debugger.h>
// STL includes
// NeL includes
// #include <nel/misc/debug.h>
// Project includes
#include <nel/3d/u_camera.h>
#include <nel/3d/u_driver.h>
#include <nel/3d/material.h>
#include <nel/3d/texture_bloom.h>
#include <nel/3d/texture_user.h>
#include <nel/3d/driver_user.h>
#include <nel/3d/u_texture.h>
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<CDriverUser *>(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<CDriverUser *>(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<CDriverUser *>(m_Driver)->setRenderTarget(*m_RightTexU, 0, 0, 0, 0);
else static_cast<CDriverUser *>(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<CDriverUser *>(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<CDriverUser *>(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<CStereoDeviceInfo> &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 */

@ -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
* <http://www.gnu.org/licenses/>.
*/
#include <nel/misc/types_nl.h>
#include <nel/3d/stereo_display.h>
// STL includes
// NeL includes
// #include <nel/misc/debug.h>
// Project includes
#include <nel/3d/stereo_ovr.h>
#include <nel/3d/stereo_libvr.h>
#include <nel/3d/stereo_debugger.h>
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 "<InvalidDeviceLibrary>";
}
void IStereoDisplay::listDevices(std::vector<CStereoDeviceInfo> &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 */

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

Loading…
Cancel
Save