Merge with default
This commit is contained in:
commit
7d0a84b2d1
124 changed files with 14747 additions and 6899 deletions
70
code/CMakeModules/FindLibOVR.cmake
Normal file
70
code/CMakeModules/FindLibOVR.cmake
Normal file
|
@ -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)
|
32
code/CMakeModules/FindLibVR.cmake
Normal file
32
code/CMakeModules/FindLibVR.cmake
Normal file
|
@ -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)
|
|
@ -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)
|
||||
|
|
|
@ -320,6 +320,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)
|
||||
|
|
|
@ -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);
|
||||
// @}
|
||||
|
||||
|
|
49
code/nel/include/nel/3d/geometry_program.h
Normal file
49
code/nel/include/nel/3d/geometry_program.h
Normal file
|
@ -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/gpu_program.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace NL3D {
|
||||
|
||||
class CGeometryProgram : public IGPUProgram
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
CGeometryProgram();
|
||||
/// Destructor
|
||||
virtual ~CGeometryProgram ();
|
||||
};
|
||||
|
||||
} // NL3D
|
||||
|
||||
|
||||
#endif // NL_GEOMETRY_PROGRAM_H
|
||||
|
||||
/* End of vertex_program.h */
|
264
code/nel/include/nel/3d/gpu_program.h
Normal file
264
code/nel/include/nel/3d/gpu_program.h
Normal file
|
@ -0,0 +1,264 @@
|
|||
/**
|
||||
* \file gpu_program.h
|
||||
* \brief IGPUProgram
|
||||
* \date 2013-09-07 15:00GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* IGPUProgram
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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_H
|
||||
#define NL3D_GPU_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 IGPUProgramDrvInfos;
|
||||
typedef std::list<IGPUProgramDrvInfos*> TGPUPrgDrvInfoPtrList;
|
||||
typedef TGPUPrgDrvInfoPtrList::iterator ItGPUPrgDrvInfoPtrList;
|
||||
|
||||
// Class for interaction of vertex program with Driver.
|
||||
// IGPUProgramDrvInfos represent the real data of the GPU program, stored into the driver (eg: just a GLint for opengl).
|
||||
class IGPUProgramDrvInfos : public NLMISC::CRefCount
|
||||
{
|
||||
private:
|
||||
IDriver *_Driver;
|
||||
ItGPUPrgDrvInfoPtrList _DriverIterator;
|
||||
|
||||
public:
|
||||
IGPUProgramDrvInfos (IDriver *drv, ItGPUPrgDrvInfoPtrList it);
|
||||
// The virtual dtor is important.
|
||||
virtual ~IGPUProgramDrvInfos(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 CGPUProgramFeatures
|
||||
{
|
||||
CGPUProgramFeatures() : 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 CGPUProgramIndex
|
||||
{
|
||||
enum TName
|
||||
{
|
||||
ModelView,
|
||||
ModelViewInverse,
|
||||
ModelViewTranspose,
|
||||
ModelViewInverseTranspose,
|
||||
|
||||
Projection,
|
||||
ProjectionInverse,
|
||||
ProjectionTranspose,
|
||||
ProjectionInverseTranspose,
|
||||
|
||||
ModelViewProjection,
|
||||
ModelViewProjectionInverse,
|
||||
ModelViewProjectionTranspose,
|
||||
ModelViewProjectionInverseTranspose,
|
||||
|
||||
Fog,
|
||||
|
||||
NUM_UNIFORMS
|
||||
};
|
||||
static const char *Names[NUM_UNIFORMS];
|
||||
uint Indices[NUM_UNIFORMS];
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief IGPUProgram
|
||||
* \date 2013-09-07 15:00GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* A generic GPU program
|
||||
*/
|
||||
class IGPUProgram : 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
|
||||
IGPUProgram::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
|
||||
CGPUProgramFeatures Features;
|
||||
|
||||
/// Map with known parameter indices, used for assembly programs
|
||||
std::map<std::string, uint> ParamIndices;
|
||||
|
||||
private:
|
||||
std::string SourceCopy;
|
||||
};
|
||||
|
||||
public:
|
||||
IGPUProgram();
|
||||
virtual ~IGPUProgram();
|
||||
|
||||
// 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(CGPUProgramIndex::TName name) const { return m_Index.Indices[name]; }
|
||||
|
||||
// Get feature information of the current program
|
||||
inline CSource *source() const { return m_Source; };
|
||||
inline const CGPUProgramFeatures &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;
|
||||
CGPUProgramIndex m_Index;
|
||||
|
||||
public:
|
||||
/// The driver information. For the driver implementation only.
|
||||
NLMISC::CRefPtr<IGPUProgramDrvInfos> m_DrvInfo;
|
||||
|
||||
}; /* class IGPUProgram */
|
||||
|
||||
} /* namespace NL3D */
|
||||
|
||||
#endif /* #ifndef NL3D_GPU_PROGRAM_H */
|
||||
|
||||
/* end of file */
|
178
code/nel/include/nel/3d/gpu_program_params.h
Normal file
178
code/nel/include/nel/3d/gpu_program_params.h
Normal file
|
@ -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 */
|
|
@ -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>
|
||||
|
||||
|
@ -171,7 +170,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,
|
||||
|
@ -183,7 +183,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};
|
||||
|
||||
|
@ -112,7 +114,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];
|
||||
|
|
49
code/nel/include/nel/3d/pixel_program.h
Normal file
49
code/nel/include/nel/3d/pixel_program.h
Normal file
|
@ -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/gpu_program.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace NL3D {
|
||||
|
||||
class CPixelProgram : public IGPUProgram
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
CPixelProgram();
|
||||
/// Destructor
|
||||
virtual ~CPixelProgram ();
|
||||
};
|
||||
|
||||
} // NL3D
|
||||
|
||||
|
||||
#endif // NL_PIXEL_PROGRAM_H
|
||||
|
||||
/* End of vertex_program.h */
|
|
@ -27,6 +27,7 @@
|
|||
#include "nel/3d/mesh_block_manager.h"
|
||||
#include "nel/3d/shadow_map_manager.h"
|
||||
#include "nel/3d/u_scene.h"
|
||||
#include "nel/3d/vertex_program.h"
|
||||
#include <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)
|
||||
|
@ -253,7 +289,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 +335,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 +418,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 */
|
134
code/nel/include/nel/3d/stereo_debugger.h
Normal file
134
code/nel/include/nel/3d/stereo_debugger.h
Normal file
|
@ -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 */
|
141
code/nel/include/nel/3d/stereo_display.h
Normal file
141
code/nel/include/nel/3d/stereo_display.h
Normal 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 */
|
73
code/nel/include/nel/3d/stereo_hmd.h
Normal file
73
code/nel/include/nel/3d/stereo_hmd.h
Normal 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 */
|
160
code/nel/include/nel/3d/stereo_libvr.h
Normal file
160
code/nel/include/nel/3d/stereo_libvr.h
Normal 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 */
|
176
code/nel/include/nel/3d/stereo_ovr.h
Normal file
176
code/nel/include/nel/3d/stereo_ovr.h
Normal 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/gpu_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
|
||||
{
|
||||
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
|
||||
class CVertexProgram : public IGPUProgram
|
||||
{
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -153,8 +153,6 @@ SOURCE_GROUP(Driver FILES
|
|||
../../include/nel/3d/scene.h
|
||||
scene_group.cpp
|
||||
../../include/nel/3d/scene_group.h
|
||||
shader.cpp
|
||||
../../include/nel/3d/shader.h
|
||||
texture.cpp
|
||||
../../include/nel/3d/texture.h
|
||||
vertex_buffer.cpp
|
||||
|
@ -164,7 +162,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
|
||||
gpu_program.cpp
|
||||
../../include/nel/3d/gpu_program.h
|
||||
gpu_program_params.cpp
|
||||
../../include/nel/3d/gpu_program_params.h)
|
||||
|
||||
SOURCE_GROUP(Font FILES
|
||||
computed_string.cpp
|
||||
|
@ -686,12 +692,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)
|
||||
|
@ -701,6 +719,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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
// in opengl, display in init texture
|
||||
if(_InitBloomEffect)
|
||||
/*if (_OriginalRenderTarget)
|
||||
{
|
||||
CTextureUser *txt = new CTextureUser(_InitText);
|
||||
if(!((CDriverUser *) _Driver)->setRenderTarget(*txt, 0, 0, _WndWidth, _WndHeight))
|
||||
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
|
||||
else if(_InitBloomEffect)
|
||||
{
|
||||
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)
|
||||
void IDriver::removeGPUPrgDrvInfoPtr(ItGPUPrgDrvInfoPtrList gpuPrgDrvInfoIt)
|
||||
{
|
||||
_ShaderDrvInfos.erase(shaderIt);
|
||||
}
|
||||
// ***************************************************************************
|
||||
void IDriver::removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt)
|
||||
{
|
||||
_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();
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
@ -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 IGPUProgramDrvInfos
|
||||
{
|
||||
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 IGPUProgramDrvInfos
|
||||
{
|
||||
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 = CVertexProgram::nelvp) const;
|
||||
|
||||
/** Compile the given vertex program, return if successful.
|
||||
* If a vertex program was set active before compilation,
|
||||
* the state of the active vertex program is undefined behaviour afterwards.
|
||||
*/
|
||||
virtual bool compileVertexProgram(CVertexProgram *program);
|
||||
|
||||
/** Set the active vertex program. This will override vertex programs specified in CMaterial render calls.
|
||||
* Also used internally by setupMaterial(CMaterial) when getVertexProgram returns NULL.
|
||||
* The vertex program is activated immediately.
|
||||
*/
|
||||
virtual bool activeVertexProgram(CVertexProgram *program);
|
||||
// @}
|
||||
|
||||
|
||||
|
||||
/// \name Pixel Program
|
||||
// @{
|
||||
|
||||
// Order of preference
|
||||
// - activePixelProgram
|
||||
// - CMaterial pass[n] PP (uses activePixelProgram, but does not override if one already set by code)
|
||||
// - PP generated from CMaterial (uses activePixelProgram, but does not override if one already set by code)
|
||||
|
||||
/** Return true if the driver supports the specified pixel program profile.
|
||||
*/
|
||||
virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const;
|
||||
|
||||
/** Compile the given pixel program, return if successful.
|
||||
* If a pixel program was set active before compilation,
|
||||
* the state of the active pixel program is undefined behaviour afterwards.
|
||||
*/
|
||||
virtual bool compilePixelProgram(CPixelProgram *program);
|
||||
|
||||
/** Set the active pixel program. This will override pixel programs specified in CMaterial render calls.
|
||||
* Also used internally by setupMaterial(CMaterial) when getPixelProgram returns NULL.
|
||||
* The pixel program is activated immediately.
|
||||
*/
|
||||
virtual bool activePixelProgram(CPixelProgram *program);
|
||||
// @}
|
||||
|
||||
|
||||
|
||||
/// \name Geometry Program
|
||||
// @{
|
||||
|
||||
// Order of preference
|
||||
// - activeGeometryProgram
|
||||
// - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code)
|
||||
// - none
|
||||
|
||||
/** Return true if the driver supports the specified pixel program profile.
|
||||
*/
|
||||
virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const { return false; }
|
||||
|
||||
/** Compile the given pixel program, return if successful.
|
||||
* If a pixel program was set active before compilation,
|
||||
* the state of the active pixel program is undefined behaviour afterwards.
|
||||
*/
|
||||
virtual bool compileGeometryProgram(CGeometryProgram *program) { return false; }
|
||||
|
||||
/** Set the active pixel program. This will override pixel programs specified in CMaterial render calls.
|
||||
* Also used internally by setupMaterial(CMaterial) when getGeometryProgram returns NULL.
|
||||
* The pixel program is activated immediately.
|
||||
*/
|
||||
virtual bool activeGeometryProgram(CGeometryProgram *program) { return false; }
|
||||
// @}
|
||||
|
||||
|
||||
|
||||
/// \name Program parameters
|
||||
// @{
|
||||
// Set parameters
|
||||
virtual void setUniform1f(TProgram program, uint index, float f0);
|
||||
virtual void setUniform2f(TProgram program, uint index, float f0, float f1);
|
||||
virtual void setUniform3f(TProgram program, uint index, float f0, float f1, float f2);
|
||||
virtual void setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3);
|
||||
virtual void setUniform1i(TProgram program, uint index, sint32 i0);
|
||||
virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1);
|
||||
virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2);
|
||||
virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3);
|
||||
virtual void setUniform1ui(TProgram program, uint index, uint32 ui0);
|
||||
virtual void setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1);
|
||||
virtual void setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2);
|
||||
virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3);
|
||||
virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v);
|
||||
virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3);
|
||||
virtual void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba);
|
||||
virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m);
|
||||
virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src);
|
||||
virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src);
|
||||
virtual void setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src);
|
||||
// Set builtin parameters
|
||||
virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform);
|
||||
virtual void setUniformFog(TProgram program, uint index);
|
||||
// Set feature parameters
|
||||
virtual bool setUniformDriver(TProgram program); // set all driver-specific features params (based on program->features->DriverFlags)
|
||||
virtual bool setUniformMaterial(TProgram program, CMaterial &material); // set all material-specific feature params (based on program->features->MaterialFlags)
|
||||
virtual void setUniformParams(TProgram program, CGPUProgramParams ¶ms); // set all user-provided params from the storage
|
||||
virtual bool isUniformProgramState() { return false; }
|
||||
// @}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
virtual void enableVertexProgramDoubleSidedColor(bool doubleSided);
|
||||
virtual bool supportVertexProgramDoubleSidedColor() const;
|
||||
|
||||
|
@ -1021,7 +1237,7 @@ public:
|
|||
* ColorOp[n] = DISABLE;
|
||||
* AlphaOp[n] = DISABLE;
|
||||
*/
|
||||
virtual bool activeShader(CShader *shd);
|
||||
bool activeShader(CD3DShaderFX *shd);
|
||||
|
||||
// Bench
|
||||
virtual void startBench (bool wantStandardDeviation = false, bool quick = false, bool reset = true);
|
||||
|
@ -1040,8 +1256,6 @@ public:
|
|||
|
||||
uint32 getMaxVertexIndex() const { return _MaxVertexIndex; }
|
||||
|
||||
bool supportPixelShaders() const { return _PixelShader; }
|
||||
|
||||
// *** Inline info
|
||||
uint inlGetNumTextStages() const { return _NbNeLTextureStages; }
|
||||
|
||||
|
@ -1892,12 +2106,21 @@ public:
|
|||
return d3dtex;
|
||||
}
|
||||
|
||||
// Get the d3dtext mirror of an existing setuped pixel program.
|
||||
static inline CPixelProgramDrvInfosD3D* getPixelProgramD3D(CPixelProgram& pixelProgram)
|
||||
{
|
||||
H_AUTO_D3D(CDriverD3D_getPixelProgramD3D);
|
||||
CPixelProgramDrvInfosD3D* d3dPixelProgram;
|
||||
d3dPixelProgram = (CPixelProgramDrvInfosD3D*)(IGPUProgramDrvInfos*)(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*)(IGPUProgramDrvInfos*)(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 & CGPUProgramFeatures::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 & CGPUProgramFeatures::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) : IGPUProgramDrvInfos (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
|
||||
IGPUProgram::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 *>((IGPUProgramDrvInfos*)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 */,
|
||||
|
|
242
code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp
Normal file
242
code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp
Normal file
|
@ -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 ¶ms)
|
||||
{
|
||||
// todo
|
||||
}
|
||||
|
||||
} // NL3D
|
|
@ -26,7 +26,7 @@ namespace NL3D
|
|||
|
||||
// ***************************************************************************
|
||||
|
||||
CVertexProgamDrvInfosD3D::CVertexProgamDrvInfosD3D(IDriver *drv, ItVtxPrgDrvInfoPtrList it) : IVertexProgramDrvInfos (drv, it)
|
||||
CVertexProgamDrvInfosD3D::CVertexProgamDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it) : IGPUProgramDrvInfos (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::compileVertexProgram(NL3D::CVertexProgram *program)
|
||||
{
|
||||
// Program setuped ?
|
||||
if (program->m_DrvInfo == NULL)
|
||||
{
|
||||
// Find nelvp
|
||||
IGPUProgram::CSource *source = NULL;
|
||||
for (uint i = 0; i < program->getSourceNb(); ++i)
|
||||
{
|
||||
if (program->getSource(i)->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
source = program->getSource(i);
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
{
|
||||
nlwarning("Direct3D driver only supports 'nelvp' profile, vertex program cannot be used");
|
||||
return false;
|
||||
}
|
||||
|
||||
_GPUPrgDrvInfos.push_front (NULL);
|
||||
ItGPUPrgDrvInfoPtrList itTex = _GPUPrgDrvInfos.begin();
|
||||
CVertexProgamDrvInfosD3D *drvInfo;
|
||||
*itTex = drvInfo = new CVertexProgamDrvInfosD3D(this, itTex);
|
||||
|
||||
// Create a driver info structure
|
||||
program->m_DrvInfo = *itTex;
|
||||
|
||||
/** Check with our parser if the program will works with other implemented extensions, too. (EXT_vertex_shader ..).
|
||||
* There are some incompatibilities.
|
||||
*/
|
||||
CVPParser parser;
|
||||
CVPParser::TProgram parsedProgram;
|
||||
std::string errorOutput;
|
||||
bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput);
|
||||
if (!result)
|
||||
{
|
||||
nlwarning("Unable to parse a vertex program :");
|
||||
nlwarning(errorOutput.c_str());
|
||||
#ifdef NL_DEBUG_D3D
|
||||
nlassert(0);
|
||||
#endif // NL_DEBUG_D3D
|
||||
return false;
|
||||
}
|
||||
|
||||
// tmp fix for Radeon 8500/9000/9200
|
||||
// Currently they hang when PaletteSkin / SkinWeight are present in the vertex declaration, but not used
|
||||
// so disable them in the vertex declaration
|
||||
// We don't use these component in vertex programs currently..
|
||||
#ifdef NL_DEBUG
|
||||
for(uint k = 0; k < parsedProgram.size(); ++k)
|
||||
{
|
||||
for(uint l = 0; l < parsedProgram[k].getNumUsedSrc(); ++l)
|
||||
{
|
||||
const CVPOperand &op = parsedProgram[k].getSrc(l);
|
||||
if (op.Type == CVPOperand::InputRegister)
|
||||
{
|
||||
nlassert(op.Value.InputRegisterValue != CVPOperand::IWeight);
|
||||
nlassert(op.Value.InputRegisterValue != CVPOperand::IPaletteSkin);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Dump the vertex program
|
||||
std::string dest;
|
||||
dump(parsedProgram, dest);
|
||||
#ifdef NL_DEBUG_D3D
|
||||
nlinfo("Assemble Vertex Shader : ");
|
||||
string::size_type lineBegin = 0;
|
||||
string::size_type lineEnd;
|
||||
while ((lineEnd = dest.find('\n', lineBegin)) != string::npos)
|
||||
{
|
||||
nlinfo(dest.substr (lineBegin, lineEnd-lineBegin).c_str());
|
||||
lineBegin = lineEnd+1;
|
||||
}
|
||||
nlinfo(dest.substr (lineBegin, lineEnd-lineBegin).c_str());
|
||||
#endif // NL_DEBUG_D3D
|
||||
|
||||
LPD3DXBUFFER pShader;
|
||||
LPD3DXBUFFER pErrorMsgs;
|
||||
if (D3DXAssembleShader (dest.c_str(), (UINT)dest.size(), NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK)
|
||||
{
|
||||
if (_DeviceInterface->CreateVertexShader((DWORD*)pShader->GetBufferPointer(), &(getVertexProgramD3D(*program)->Shader)) != D3D_OK)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
nlwarning ("Can't assemble vertex program:");
|
||||
nlwarning ((const char*)pErrorMsgs->GetBufferPointer());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set parameters for assembly programs
|
||||
drvInfo->ParamIndices = source->ParamIndices;
|
||||
|
||||
// Build the feature info
|
||||
program->buildInfo(source);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverD3D::activeVertexProgram (CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_D3D(CDriverD3D_activeVertexProgram )
|
||||
if (_DisableHardwareVertexProgram)
|
||||
return false;
|
||||
|
||||
// Setup or unsetup ?
|
||||
if (program)
|
||||
{
|
||||
// Program setuped ?
|
||||
if (program->_DrvInfo==NULL)
|
||||
{
|
||||
_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)
|
||||
{
|
||||
nlwarning("Unable to parse a vertex program :");
|
||||
nlwarning(errorOutput.c_str());
|
||||
#ifdef NL_DEBUG_D3D
|
||||
nlassert(0);
|
||||
#endif // NL_DEBUG_D3D
|
||||
return false;
|
||||
}
|
||||
|
||||
// tmp fix for Radeon 8500/9000/9200
|
||||
// Currently they hang when PaletteSkin / SkinWeight are present in the vertex declaration, but not used
|
||||
// so disable them in the vertex declaration
|
||||
// We don't use these component in vertex programs currently..
|
||||
#ifdef NL_DEBUG
|
||||
for(uint k = 0; k < parsedProgram.size(); ++k)
|
||||
{
|
||||
for(uint l = 0; l < parsedProgram[k].getNumUsedSrc(); ++l)
|
||||
{
|
||||
const CVPOperand &op = parsedProgram[k].getSrc(l);
|
||||
if (op.Type == CVPOperand::InputRegister)
|
||||
{
|
||||
nlassert(op.Value.InputRegisterValue != CVPOperand::IWeight);
|
||||
nlassert(op.Value.InputRegisterValue != CVPOperand::IPaletteSkin);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Dump the vertex program
|
||||
std::string dest;
|
||||
dump(parsedProgram, dest);
|
||||
#ifdef NL_DEBUG_D3D
|
||||
nlinfo("Assemble Vertex Shader : ");
|
||||
string::size_type lineBegin = 0;
|
||||
string::size_type lineEnd;
|
||||
while ((lineEnd = dest.find('\n', lineBegin)) != string::npos)
|
||||
{
|
||||
nlinfo(dest.substr (lineBegin, lineEnd-lineBegin).c_str());
|
||||
lineBegin = lineEnd+1;
|
||||
}
|
||||
nlinfo(dest.substr (lineBegin, lineEnd-lineBegin).c_str());
|
||||
#endif // NL_DEBUG_D3D
|
||||
|
||||
LPD3DXBUFFER pShader;
|
||||
LPD3DXBUFFER pErrorMsgs;
|
||||
if (D3DXAssembleShader (dest.c_str(), (UINT)dest.size(), NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK)
|
||||
{
|
||||
if (_DeviceInterface->CreateVertexShader((DWORD*)pShader->GetBufferPointer(), &(getVertexProgramD3D(*program)->Shader)) != D3D_OK)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
nlwarning ("Can't assemble vertex program:");
|
||||
nlwarning ((const char*)pErrorMsgs->GetBufferPointer());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set 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 *>((IGPUProgramDrvInfos*)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() && 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.
|
||||
|
@ -1409,11 +1415,13 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1535,9 +1543,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 +1555,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 +1995,6 @@ static void fetchPerturbedEnvMapR200()
|
|||
#endif
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
void CDriverGL::forceNativeFragmentPrograms(bool nativeOnly)
|
||||
{
|
||||
_ForceNativeFragmentPrograms = nativeOnly;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
void CDriverGL::initFragmentShaders()
|
||||
{
|
||||
|
@ -2567,14 +2569,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,158 @@ 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
|
||||
|
||||
/**
|
||||
* 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 = CVertexProgram::nelvp) 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
|
||||
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)
|
||||
bool setUniformMaterialInternal(TProgram program, CMaterial &material); // set all material-specific feature params (based on program->features->MaterialFlags)
|
||||
virtual void setUniformParams(TProgram program, CGPUProgramParams ¶ms); // set all user-provided params from the storage
|
||||
virtual bool isUniformProgramState() { return false; }
|
||||
// @}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
virtual void enableVertexProgramDoubleSidedColor(bool doubleSided);
|
||||
virtual bool supportVertexProgramDoubleSidedColor() const;
|
||||
|
||||
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 +1463,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 +1629,7 @@ private:
|
|||
};
|
||||
|
||||
// ***************************************************************************
|
||||
class CVertexProgamDrvInfosGL : public IVertexProgramDrvInfos
|
||||
class CVertexProgamDrvInfosGL : public IGPUProgramDrvInfos
|
||||
{
|
||||
public:
|
||||
// The GL Id.
|
||||
|
@ -1517,7 +1650,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 IGPUProgramDrvInfos
|
||||
{
|
||||
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 & CGPUProgramFeatures::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 & CGPUProgramFeatures::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 & CGPUProgramFeatures::TextureMatrices))
|
||||
)
|
||||
{
|
||||
setupUserTextureMatrix(inlGetNumTextStages(), mat);
|
||||
}
|
||||
else // deactivate texture matrix
|
||||
else
|
||||
{
|
||||
disableUserTextureMatrix();
|
||||
}
|
||||
|
|
236
code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp
Normal file
236
code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp
Normal file
|
@ -0,0 +1,236 @@
|
|||
/** \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) : IGPUProgramDrvInfos (drv, it)
|
||||
{
|
||||
H_AUTO_OGL(CPixelProgamDrvInfosGL_CPixelProgamDrvInfosGL)
|
||||
// Extension must exist
|
||||
nlassert(drv->_Extensions.ARBFragmentProgram);
|
||||
|
||||
if (drv->_Extensions.ARBFragmentProgram) // ARB implementation
|
||||
{
|
||||
nglGenProgramsARB(1, &ID);
|
||||
}
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
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)
|
||||
{
|
||||
// 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::IGPUProgramDrvInfos*)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;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL::activeARBPixelProgram(CPixelProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_activeARBPixelProgram)
|
||||
|
||||
// Setup or unsetup ?
|
||||
if (program)
|
||||
{
|
||||
// Program setuped ?
|
||||
if (!CDriverGL::compilePixelProgram(program)) return false;
|
||||
|
||||
// Cast the driver info pointer
|
||||
CPixelProgamDrvInfosGL *drvInfo = safe_cast<CPixelProgamDrvInfosGL*>((IGPUProgramDrvInfos*)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;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &specularWritten*/)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setupARBPixelProgram)
|
||||
|
||||
CPixelProgamDrvInfosGL *drvInfo = static_cast<CPixelProgamDrvInfosGL *>((IGPUProgramDrvInfos *)program->m_DrvInfo);
|
||||
|
||||
// Find a supported pixel program profile
|
||||
IGPUProgram::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;
|
||||
}
|
||||
|
||||
#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,
|
||||
|
|
495
code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp
Normal file
495
code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp
Normal file
|
@ -0,0 +1,495 @@
|
|||
// 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::setUniform4f(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::setUniform4fv(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::setUniform4f(program, index, f0, 0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform2f(TProgram program, uint index, float f0, float f1)
|
||||
{
|
||||
CDriverGL::setUniform4f(program, index, f0, f1, 0.f, 0.f);
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform3f(TProgram program, uint index, float f0, float f1, float f2)
|
||||
{
|
||||
CDriverGL::setUniform4f(program, index, f0, f1, f2, 0.0f);
|
||||
}
|
||||
|
||||
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::setUniform4f(program, index, v.x, v.y, v.z, 0.f);
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3)
|
||||
{
|
||||
CDriverGL::setUniform4f(program, index, v.x, v.y, v.z, f3);
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba)
|
||||
{
|
||||
CDriverGL::setUniform4fv(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::setUniform4fv(program, index, 4, md);
|
||||
}
|
||||
|
||||
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::setUniform4fv(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::setUniform4f(program, index, -values[2], -values[6], -values[10], -values[14]);
|
||||
}
|
||||
|
||||
bool CDriverGL::setUniformDriver(TProgram program)
|
||||
{
|
||||
IGPUProgram *prog = NULL;
|
||||
switch (program)
|
||||
{
|
||||
case VertexProgram:
|
||||
prog = _LastSetuppedVP;
|
||||
break;
|
||||
case PixelProgram:
|
||||
prog = _LastSetuppedPP;
|
||||
break;
|
||||
}
|
||||
if (!prog) return false;
|
||||
|
||||
const CGPUProgramFeatures &features = prog->features();
|
||||
|
||||
if (features.DriverFlags)
|
||||
{
|
||||
if (features.DriverFlags & CGPUProgramFeatures::Matrices)
|
||||
{
|
||||
if (prog->getUniformIndex(CGPUProgramIndex::ModelView) != ~0)
|
||||
{
|
||||
setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelView), ModelView, Identity);
|
||||
}
|
||||
if (prog->getUniformIndex(CGPUProgramIndex::ModelViewInverse) != ~0)
|
||||
{
|
||||
setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewInverse), ModelView, Inverse);
|
||||
}
|
||||
if (prog->getUniformIndex(CGPUProgramIndex::ModelViewTranspose) != ~0)
|
||||
{
|
||||
setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewTranspose), ModelView, Transpose);
|
||||
}
|
||||
if (prog->getUniformIndex(CGPUProgramIndex::ModelViewInverseTranspose) != ~0)
|
||||
{
|
||||
setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewInverseTranspose), ModelView, InverseTranspose);
|
||||
}
|
||||
if (prog->getUniformIndex(CGPUProgramIndex::Projection) != ~0)
|
||||
{
|
||||
setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::Projection), Projection, Identity);
|
||||
}
|
||||
if (prog->getUniformIndex(CGPUProgramIndex::ProjectionInverse) != ~0)
|
||||
{
|
||||
setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ProjectionInverse), Projection, Inverse);
|
||||
}
|
||||
if (prog->getUniformIndex(CGPUProgramIndex::ProjectionTranspose) != ~0)
|
||||
{
|
||||
setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ProjectionTranspose), Projection, Transpose);
|
||||
}
|
||||
if (prog->getUniformIndex(CGPUProgramIndex::ProjectionInverseTranspose) != ~0)
|
||||
{
|
||||
setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ProjectionInverseTranspose), Projection, InverseTranspose);
|
||||
}
|
||||
if (prog->getUniformIndex(CGPUProgramIndex::ModelViewProjection) != ~0)
|
||||
{
|
||||
setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjection), ModelViewProjection, Identity);
|
||||
}
|
||||
if (prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionInverse) != ~0)
|
||||
{
|
||||
setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionInverse), ModelViewProjection, Inverse);
|
||||
}
|
||||
if (prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionTranspose) != ~0)
|
||||
{
|
||||
setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionTranspose), ModelViewProjection, Transpose);
|
||||
}
|
||||
if (prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionInverseTranspose) != ~0)
|
||||
{
|
||||
setUniformMatrix(program, prog->getUniformIndex(CGPUProgramIndex::ModelViewProjectionInverseTranspose), ModelViewProjection, InverseTranspose);
|
||||
}
|
||||
}
|
||||
if (features.DriverFlags & CGPUProgramFeatures::Fog)
|
||||
{
|
||||
if (prog->getUniformIndex(CGPUProgramIndex::Fog) != ~0)
|
||||
{
|
||||
setUniformFog(program, prog->getUniformIndex(CGPUProgramIndex::Fog));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDriverGL::setUniformMaterial(TProgram program, CMaterial &material)
|
||||
{
|
||||
IGPUProgram *prog = NULL;
|
||||
switch (program)
|
||||
{
|
||||
case VertexProgram:
|
||||
prog = _LastSetuppedVP;
|
||||
break;
|
||||
case PixelProgram:
|
||||
prog = _LastSetuppedPP;
|
||||
break;
|
||||
}
|
||||
if (!prog) return false;
|
||||
|
||||
const CGPUProgramFeatures &features = prog->features();
|
||||
|
||||
// These are also already set by setupMaterial, so setupMaterial uses setUniformMaterialInternal instead
|
||||
if (features.MaterialFlags & (CGPUProgramFeatures::TextureStages | CGPUProgramFeatures::TextureMatrices))
|
||||
{
|
||||
if (features.MaterialFlags & CGPUProgramFeatures::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 & CGPUProgramFeatures::TextureMatrices)
|
||||
{
|
||||
// Textures user matrix
|
||||
setupUserTextureMatrix(inlGetNumTextStages(), material);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDriverGL::setUniformMaterialInternal(TProgram program, CMaterial &material)
|
||||
{
|
||||
IGPUProgram *prog = NULL;
|
||||
switch (program)
|
||||
{
|
||||
case VertexProgram:
|
||||
prog = _LastSetuppedVP;
|
||||
break;
|
||||
case PixelProgram:
|
||||
prog = _LastSetuppedPP;
|
||||
break;
|
||||
}
|
||||
if (!prog) return false;
|
||||
|
||||
const CGPUProgramFeatures &features = prog->features();
|
||||
|
||||
if (features.MaterialFlags & ~(CGPUProgramFeatures::TextureStages | CGPUProgramFeatures::TextureMatrices))
|
||||
{
|
||||
// none
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDriverGL::setUniformParams(TProgram program, CGPUProgramParams ¶ms)
|
||||
{
|
||||
IGPUProgram *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 *>((IGPUProgramDrvInfos *) 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 *>((IGPUProgramDrvInfos *) 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) : IGPUProgramDrvInfos (drv, it)
|
||||
{
|
||||
H_AUTO_OGL(CVertexProgamDrvInfosGL_CVertexProgamDrvInfosGL);
|
||||
|
||||
|
@ -70,23 +70,136 @@ 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::compileNVVertexProgram(CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_compileNVVertexProgram);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
|
||||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
|
||||
nlassert(!program->m_DrvInfo);
|
||||
glDisable(GL_VERTEX_PROGRAM_NV);
|
||||
_VertexProgramEnabled = false;
|
||||
|
||||
// Find nelvp
|
||||
IGPUProgram::CSource *source = NULL;
|
||||
for (uint i = 0; i < program->getSourceNb(); ++i)
|
||||
{
|
||||
if (program->getSource(i)->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
source = program->getSource(i);
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
{
|
||||
nlwarning("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;
|
||||
}
|
||||
|
||||
// Insert into driver list. (so it is deleted when driver is deleted).
|
||||
ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)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))
|
||||
{
|
||||
if (sString[offset]=='\n')
|
||||
{
|
||||
line++;
|
||||
charC=1;
|
||||
}
|
||||
else
|
||||
charC++;
|
||||
|
||||
// Next character
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Show the error
|
||||
nlwarning("3D: Vertex program syntax error line %d character %d\n", line, charC);
|
||||
|
||||
// Setup not ok
|
||||
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);
|
||||
|
||||
// Setup ok
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
bool CDriverGL::activeNVVertexProgram (CVertexProgram *program)
|
||||
bool CDriverGL::activeNVVertexProgram(CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CVertexProgamDrvInfosGL_activeNVVertexProgram);
|
||||
|
||||
|
@ -94,99 +207,16 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program)
|
|||
// Setup or unsetup ?
|
||||
if (program)
|
||||
{
|
||||
// Enable vertex program
|
||||
glEnable (GL_VERTEX_PROGRAM_NV);
|
||||
_VertexProgramEnabled= true;
|
||||
|
||||
|
||||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->m_DrvInfo);
|
||||
nlassert(drvInfo);
|
||||
|
||||
// Program setuped ?
|
||||
if (program->_DrvInfo==NULL)
|
||||
{
|
||||
/** 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)
|
||||
{
|
||||
nlwarning("Unable to parse a vertex program :");
|
||||
nlwarning(errorOutput.c_str());
|
||||
#ifdef NL_DEBUG
|
||||
nlassert(0);
|
||||
#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;
|
||||
|
||||
// Compile the program
|
||||
nglLoadProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)program->getProgram().length(), (const GLubyte*)program->getProgram().c_str());
|
||||
|
||||
// Get loading error code
|
||||
GLint errorOff;
|
||||
glGetIntegerv (GL_PROGRAM_ERROR_POSITION_NV, &errorOff);
|
||||
|
||||
// Compilation error ?
|
||||
if (errorOff>=0)
|
||||
{
|
||||
// String length
|
||||
uint length = (uint)program->getProgram ().length();
|
||||
const char* sString= program->getProgram ().c_str();
|
||||
|
||||
// Line count and char count
|
||||
uint line=1;
|
||||
uint charC=1;
|
||||
|
||||
// Find the line
|
||||
uint offset=0;
|
||||
while ((offset<length)&&(offset<(uint)errorOff))
|
||||
{
|
||||
if (sString[offset]=='\n')
|
||||
{
|
||||
line++;
|
||||
charC=1;
|
||||
}
|
||||
else
|
||||
charC++;
|
||||
|
||||
// Next character
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Show the error
|
||||
nlwarning("3D: Vertex program syntax error line %d character %d\n", line, charC);
|
||||
|
||||
// Disable vertex program
|
||||
glDisable (GL_VERTEX_PROGRAM_NV);
|
||||
_VertexProgramEnabled= false;
|
||||
|
||||
// Setup not ok
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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,165 +1516,273 @@ bool CDriverGL::setupARBVertexProgram (const CVPParser::TProgram &inParsedProgra
|
|||
#endif
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL::compileARBVertexProgram(NL3D::CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_compileARBVertexProgram);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
|
||||
nlassert(!program->m_DrvInfo);
|
||||
glDisable(GL_VERTEX_PROGRAM_ARB);
|
||||
_VertexProgramEnabled = false;
|
||||
|
||||
// Find nelvp
|
||||
IGPUProgram::CSource *source = NULL;
|
||||
for (uint i = 0; i < program->getSourceNb(); ++i)
|
||||
{
|
||||
if (program->getSource(i)->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
source = program->getSource(i);
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
{
|
||||
nlwarning("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::IGPUProgramDrvInfos*)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::activeARBVertexProgram (CVertexProgram *program)
|
||||
|
||||
bool CDriverGL::activeARBVertexProgram(CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_activeARBVertexProgram);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
|
||||
// Setup or unsetup ?
|
||||
if (program)
|
||||
{
|
||||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->m_DrvInfo);
|
||||
nlassert(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;
|
||||
|
||||
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 );
|
||||
nglBindProgramARB(GL_VERTEX_PROGRAM_ARB, drvInfo->ID);
|
||||
if (drvInfo->SpecularWritten)
|
||||
{
|
||||
glEnable( GL_COLOR_SUM_ARB );
|
||||
glEnable(GL_COLOR_SUM_ARB);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable( GL_COLOR_SUM_ARB ); // no specular written
|
||||
glDisable(GL_COLOR_SUM_ARB); // no specular written
|
||||
}
|
||||
_LastSetuppedVP = program;
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable( GL_VERTEX_PROGRAM_ARB );
|
||||
glDisable( GL_COLOR_SUM_ARB );
|
||||
glDisable(GL_VERTEX_PROGRAM_ARB);
|
||||
glDisable(GL_COLOR_SUM_ARB);
|
||||
_VertexProgramEnabled = false;
|
||||
}
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
bool CDriverGL::activeEXTVertexShader (CVertexProgram *program)
|
||||
|
||||
bool CDriverGL::compileEXTVertexShader(CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_activeEXTVertexShader);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
// Setup or unsetup ?
|
||||
if (program)
|
||||
|
||||
nlassert(program->m_DrvInfo);
|
||||
glDisable(GL_VERTEX_SHADER_EXT);
|
||||
_VertexProgramEnabled = false;
|
||||
|
||||
// Find nelvp
|
||||
IGPUProgram::CSource *source = NULL;
|
||||
for (uint i = 0; i < program->getSourceNb(); ++i)
|
||||
{
|
||||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
|
||||
// Program setuped ?
|
||||
if (program->_DrvInfo==NULL)
|
||||
if (program->getSource(i)->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
source = program->getSource(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cast the driver info pointer
|
||||
drvInfo=safe_cast<CVertexProgamDrvInfosGL*>((IVertexProgramDrvInfos*)program->_DrvInfo);
|
||||
}
|
||||
|
||||
glEnable( GL_VERTEX_SHADER_EXT);
|
||||
_VertexProgramEnabled = true;
|
||||
nglBindVertexShaderEXT( drvInfo->ID );
|
||||
_LastSetuppedVP = program;
|
||||
}
|
||||
else
|
||||
if (!source)
|
||||
{
|
||||
glDisable( GL_VERTEX_SHADER_EXT );
|
||||
_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;
|
||||
}
|
||||
|
||||
/*
|
||||
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::IGPUProgramDrvInfos*)NULL);
|
||||
|
||||
// Create a driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
*it = drvInfo = new CVertexProgamDrvInfosGL (this, it);
|
||||
// Set the pointer
|
||||
program->m_DrvInfo=drvInfo;
|
||||
|
||||
if (!setupEXTVertexShader(parsedProgram, drvInfo->ID, drvInfo->Variants, drvInfo->UsedVertexComponents))
|
||||
{
|
||||
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::activeVertexProgram (CVertexProgram *program)
|
||||
|
||||
bool CDriverGL::activeEXTVertexShader(CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_activeEXTVertexShader);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
|
||||
// Setup or unsetup ?
|
||||
if (program)
|
||||
{
|
||||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->m_DrvInfo);
|
||||
nlassert(drvInfo);
|
||||
|
||||
glEnable(GL_VERTEX_SHADER_EXT);
|
||||
_VertexProgramEnabled = true;
|
||||
nglBindVertexShaderEXT(drvInfo->ID);
|
||||
_LastSetuppedVP = program;
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_VERTEX_SHADER_EXT);
|
||||
_VertexProgramEnabled = false;
|
||||
}
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CDriverGL::compileVertexProgram(NL3D::CVertexProgram *program)
|
||||
{
|
||||
if (program->m_DrvInfo == NULL)
|
||||
{
|
||||
// Extension
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
return compileNVVertexProgram(program);
|
||||
}
|
||||
else if (_Extensions.ARBVertexProgram)
|
||||
{
|
||||
return compileARBVertexProgram(program);
|
||||
}
|
||||
else if (_Extensions.EXTVertexShader)
|
||||
{
|
||||
return compileEXTVertexShader(program);
|
||||
}
|
||||
|
||||
// Can't do anything
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL::activeVertexProgram(CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_activeVertexProgram)
|
||||
// Extension here ?
|
||||
|
||||
// Compile if necessary
|
||||
if (program && !CDriverGL::compileVertexProgram(program)) return false;
|
||||
|
||||
// Extension
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
return activeNVVertexProgram(program);
|
||||
|
@ -1662,287 +1800,6 @@ bool CDriverGL::activeVertexProgram (CVertexProgram *program)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setConstant (uint index, float f0, float f1, float f2, float f3)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstant);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
// Vertex program exist ?
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setConstant (uint index, double d0, double d1, double d2, double d3)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstant);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
// Vertex program exist ?
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setConstant (uint index, const NLMISC::CVector& value)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstant);
|
||||
|
||||
#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)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstant);
|
||||
|
||||
#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)
|
||||
{
|
||||
nglProgramEnvParameter4dARB(GL_VERTEX_PROGRAM_ARB, index, value.x, value.y, value.z, 0);
|
||||
}
|
||||
else if (_Extensions.EXTVertexShader)
|
||||
{
|
||||
double datas[] = { value.x, value.y, value.z, 0 };
|
||||
nglSetInvariantEXT(_EVSConstantHandle + index, GL_DOUBLE, datas);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
void CDriverGL::setConstant (uint index, uint num, const float *src)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstant);
|
||||
|
||||
#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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
for(uint k = 0; k < num; ++k)
|
||||
{
|
||||
nglProgramEnvParameter4dvARB(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_DOUBLE, (void *) (src + 4 * k));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
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::setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstantMatrix);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
// Vertex program exist ?
|
||||
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);
|
||||
}
|
||||
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();
|
||||
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);
|
||||
}
|
||||
}
|
||||
#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]);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::enableVertexProgramDoubleSidedColor(bool doubleSided)
|
||||
|
|
|
@ -213,6 +213,12 @@ void CDriverUser::disableHardwareVertexProgram()
|
|||
|
||||
_Driver->disableHardwareVertexProgram();
|
||||
}
|
||||
void CDriverUser::disableHardwarePixelProgram()
|
||||
{
|
||||
NL3D_HAUTO_UI_DRIVER;
|
||||
|
||||
_Driver->disableHardwarePixelProgram();
|
||||
}
|
||||
void CDriverUser::disableHardwareVertexArrayAGP()
|
||||
{
|
||||
NL3D_HAUTO_UI_DRIVER;
|
||||
|
@ -1490,12 +1496,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
|
||||
|
|
49
code/nel/src/3d/geometry_program.cpp
Normal file
49
code/nel/src/3d/geometry_program.cpp
Normal file
|
@ -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
|
117
code/nel/src/3d/gpu_program.cpp
Normal file
117
code/nel/src/3d/gpu_program.cpp
Normal file
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* \file gpu_program.cpp
|
||||
* \brief IGPUProgram
|
||||
* \date 2013-09-07 15:00GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* IGPUProgram
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.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 {
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
IGPUProgramDrvInfos::IGPUProgramDrvInfos(IDriver *drv, ItGPUPrgDrvInfoPtrList it)
|
||||
{
|
||||
_Driver = drv;
|
||||
_DriverIterator = it;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
IGPUProgramDrvInfos::~IGPUProgramDrvInfos ()
|
||||
{
|
||||
_Driver->removeGPUPrgDrvInfoPtr(_DriverIterator);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
IGPUProgram::IGPUProgram()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
IGPUProgram::~IGPUProgram()
|
||||
{
|
||||
// Must kill the drv mirror of this program.
|
||||
m_DrvInfo.kill();
|
||||
}
|
||||
|
||||
const char *CGPUProgramIndex::Names[NUM_UNIFORMS] =
|
||||
{
|
||||
"modelView",
|
||||
"modelViewInverse",
|
||||
"modelViewTranspose",
|
||||
"modelViewInverseTranspose",
|
||||
|
||||
"projection",
|
||||
"projectionInverse",
|
||||
"projectionTranspose",
|
||||
"projectionInverseTranspose",
|
||||
|
||||
"modelViewProjection",
|
||||
"modelViewProjectionInverse",
|
||||
"modelViewProjectionTranspose",
|
||||
"modelViewProjectionInverseTranspose",
|
||||
|
||||
"fog",
|
||||
};
|
||||
|
||||
void IGPUProgram::buildInfo(CSource *source)
|
||||
{
|
||||
nlassert(!m_Source);
|
||||
|
||||
m_Source = source;
|
||||
|
||||
// Fill index cache
|
||||
for (int i = 0; i < CGPUProgramIndex::NUM_UNIFORMS; ++i)
|
||||
{
|
||||
m_Index.Indices[i] = getUniformIndex(m_Index.Names[i]);
|
||||
}
|
||||
|
||||
buildInfo();
|
||||
}
|
||||
|
||||
void IGPUProgram::buildInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} /* namespace NL3D */
|
||||
|
||||
/* end of file */
|
587
code/nel/src/3d/gpu_program_params.cpp
Normal file
587
code/nel/src/3d/gpu_program_params.cpp
Normal file
|
@ -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 */
|
|
@ -574,7 +574,7 @@ void CLandscape::setDriver(IDriver *drv)
|
|||
|
||||
// Does the driver support VertexShader???
|
||||
// only if VP supported by GPU.
|
||||
_VertexShaderOk= (_Driver->isVertexProgramSupported() && !_Driver->isVertexProgramEmulated());
|
||||
_VertexShaderOk= (_Driver->supportVertexProgram() && !_Driver->isVertexProgramEmulated());
|
||||
|
||||
|
||||
// Does the driver has sufficient requirements for Vegetable???
|
||||
|
@ -1193,20 +1193,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(CGPUProgramIndex::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(CGPUProgramIndex::Fog));
|
||||
// c[12] take the current landscape Center / delta Pos to apply
|
||||
driver->setUniform3f(IDriver::VertexProgram, program->idx().PZBModelPosition, _PZBModelPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ 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->supportVertexProgram() && !_Driver->isVertexProgramEmulated());
|
||||
|
||||
// must reallocate the VertexBuffer.
|
||||
if( _NumVerticesAllocated>0 )
|
||||
|
@ -247,14 +247,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 +525,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 +568,7 @@ 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);
|
||||
}
|
||||
else if(_Type==Far1)
|
||||
{
|
||||
|
@ -577,9 +583,7 @@ 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -594,20 +598,74 @@ 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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
|
|
@ -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/misc/stream.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 :)
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
// \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()));
|
||||
_VertexProgram[vp] = new CVertexProgramPerPixelLight(vp);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,7 +500,7 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv,
|
|||
{
|
||||
// test if supported by driver
|
||||
if (!
|
||||
(drv->isVertexProgramSupported()
|
||||
(drv->supportVertexProgram()
|
||||
&& !drv->isVertexProgramEmulated()
|
||||
&& drv->supportPerPixelLighting(SpecularLighting)
|
||||
)
|
||||
|
@ -437,11 +509,13 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv,
|
|||
return false;
|
||||
}
|
||||
//
|
||||
enable(true, drv); // must enable the vertex program before the vb is activated
|
||||
CVertexProgramPerPixelLight *program = _ActiveVertexProgram;
|
||||
nlassert(program);
|
||||
//
|
||||
CRenderTrav *renderTrav= &scene->getRenderTrav();
|
||||
/// Setup for gouraud lighting
|
||||
renderTrav->beginVPLightSetup(VPLightConstantStart,
|
||||
SpecularLighting,
|
||||
invertedModelMat);
|
||||
renderTrav->beginVPLightSetup(program, invertedModelMat);
|
||||
//
|
||||
sint strongestLightIndex = renderTrav->getStrongestLightIndex();
|
||||
if (strongestLightIndex == -1) return false; // if no strongest light, disable this vertex program
|
||||
|
@ -455,7 +529,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 +537,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 +551,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(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -521,11 +593,13 @@ void CMeshVPPerPixelLight::enable(bool enabled, IDriver *drv)
|
|||
| (SpecularLighting ? 2 : 0)
|
||||
| (_IsPointLight ? 1 : 0);
|
||||
//
|
||||
drv->activeVertexProgram(_VertexProgram[idVP].get());
|
||||
drv->activeVertexProgram((CVertexProgramPerPixelLight *)_VertexProgram[idVP]);
|
||||
_ActiveVertexProgram = _VertexProgram[idVP];
|
||||
}
|
||||
else
|
||||
{
|
||||
drv->activeVertexProgram(NULL);
|
||||
_ActiveVertexProgram = NULL;
|
||||
}
|
||||
_Enabled = enabled;
|
||||
}
|
||||
|
@ -538,6 +612,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 +623,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)
|
||||
{
|
||||
|
@ -142,9 +219,6 @@ void CMeshVPWindTree::initInstance(CMeshBaseInstance *mbi)
|
|||
// 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,11 +227,8 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,21 +274,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 +315,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(CGPUProgramIndex::ModelViewProjection),
|
||||
IDriver::ModelViewProjection, IDriver::Identity);
|
||||
// c[4..7] take the ModelView Matrix. After setupModelMatrix();00
|
||||
driver->setConstantFog(6);
|
||||
driver->setUniformFog(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::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 +334,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,22 +355,46 @@ 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->supportVertexProgram() && !driver->isVertexProgramEmulated())) return false;
|
||||
|
||||
|
||||
// Activate the good VertexProgram
|
||||
//===============
|
||||
|
||||
|
||||
// Get how many pointLights are setuped now.
|
||||
nlassert(scene != NULL);
|
||||
CRenderTrav *renderTrav= &scene->getRenderTrav();
|
||||
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]);
|
||||
_ActiveVertexProgram = _VertexProgram[idVP];
|
||||
|
||||
|
||||
// precompute mesh
|
||||
|
@ -296,22 +403,7 @@ bool CMeshVPWindTree::begin(IDriver *driver, CScene *scene, CMeshBaseInstance *m
|
|||
// Setup instance constants
|
||||
setupPerInstanceConstants(driver, scene, mbi, invertedModelMat);
|
||||
|
||||
// Activate the good VertexProgram
|
||||
//===============
|
||||
|
||||
// Get how many pointLights are setuped now.
|
||||
nlassert(scene != NULL);
|
||||
CRenderTrav *renderTrav= &scene->getRenderTrav();
|
||||
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());
|
||||
|
||||
|
||||
return true;
|
||||
|
@ -322,6 +414,7 @@ void CMeshVPWindTree::end(IDriver *driver)
|
|||
{
|
||||
// Disable the VertexProgram
|
||||
driver->activeVertexProgram(NULL);
|
||||
_ActiveVertexProgram = NULL;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
@ -347,7 +440,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,30 +461,29 @@ bool CMeshVPWindTree::supportMeshBlockRendering() const
|
|||
// ***************************************************************************
|
||||
bool CMeshVPWindTree::isMBRVpOk(IDriver *driver) const
|
||||
{
|
||||
return driver->isVertexProgramSupported() && !driver->isVertexProgramEmulated();
|
||||
return driver->supportVertexProgram() && !driver->isVertexProgramEmulated();
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
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();
|
||||
|
@ -398,16 +491,27 @@ void CMeshVPWindTree::beginMBRInstance(IDriver *driver, CScene *scene, CMeshBase
|
|||
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 +519,7 @@ void CMeshVPWindTree::endMBRMesh(IDriver *driver)
|
|||
{
|
||||
// Disable the VertexProgram
|
||||
driver->activeVertexProgram(NULL);
|
||||
_ActiveVertexProgram = NULL;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
|
49
code/nel/src/3d/pixel_program.cpp
Normal file
49
code/nel/src/3d/pixel_program.cpp
Normal file
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -762,13 +762,15 @@ void CRenderTrav::changeLightSetup(CLightContribution *lightContribution, bool
|
|||
|
||||
|
||||
// ***************************************************************************
|
||||
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;
|
||||
// _VPCurrentCtStart= ctStart;
|
||||
// _VPSupportSpecular= supportSpecular;
|
||||
_VPCurrent = program;
|
||||
bool supportSpecular = program->featuresLighted().SupportSpecular;
|
||||
|
||||
// Prepare Colors (to be multiplied by material)
|
||||
//================
|
||||
|
@ -786,8 +788,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 +805,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 +824,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 +852,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 +864,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 +894,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 +903,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 +912,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 +938,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 +954,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);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
@ -1168,8 +1160,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();
|
||||
|
|
|
@ -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);
|
||||
|
|
463
code/nel/src/3d/stereo_debugger.cpp
Normal file
463
code/nel/src/3d/stereo_debugger.cpp
Normal file
|
@ -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
|
||||
{
|
||||
IGPUProgram::CSource *source = new IGPUProgram::CSource();
|
||||
source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages;
|
||||
source->Profile = IGPUProgram::arbfp1;
|
||||
source->setSourcePtr(a_arbfp1);
|
||||
m_PixelProgram->addSource(source);
|
||||
}
|
||||
// ps_2_0
|
||||
{
|
||||
IGPUProgram::CSource *source = new IGPUProgram::CSource();
|
||||
source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages;
|
||||
source->Profile = IGPUProgram::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 */
|
112
code/nel/src/3d/stereo_display.cpp
Normal file
112
code/nel/src/3d/stereo_display.cpp
Normal 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 */
|
55
code/nel/src/3d/stereo_hmd.cpp
Normal file
55
code/nel/src/3d/stereo_hmd.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* \file stereo_hmd.cpp
|
||||
* \brief IStereoHMD
|
||||
* \date 2013-06-27 16:30GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* IStereoHMD
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 by authors
|
||||
*
|
||||
* This file is part of NL3D.
|
||||
* NL3D is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* NL3D is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with NL3D. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include <nel/3d/stereo_hmd.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// NeL includes
|
||||
// #include <nel/misc/debug.h>
|
||||
|
||||
// Project includes
|
||||
|
||||
using namespace std;
|
||||
// using namespace NLMISC;
|
||||
|
||||
namespace NL3D {
|
||||
|
||||
IStereoHMD::IStereoHMD()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IStereoHMD::~IStereoHMD()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} /* namespace NL3D */
|
||||
|
||||
/* end of file */
|
642
code/nel/src/3d/stereo_libvr.cpp
Normal file
642
code/nel/src/3d/stereo_libvr.cpp
Normal file
|
@ -0,0 +1,642 @@
|
|||
/**
|
||||
* \file stereo_libvr.cpp
|
||||
* \brief CStereoLibVR
|
||||
* \date 2013-08-19 19:17MT
|
||||
* \author Thibaut Girka (ThibG)
|
||||
* CStereoLibVR
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 by authors
|
||||
*
|
||||
* This file is part of NL3D.
|
||||
* NL3D is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* NL3D is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with NL3D. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_LIBVR
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include <nel/misc/time_nl.h>
|
||||
#include <nel/3d/stereo_libvr.h>
|
||||
|
||||
// STL includes
|
||||
#include <sstream>
|
||||
|
||||
// External includes
|
||||
extern "C" {
|
||||
#include <hmd.h>
|
||||
}
|
||||
|
||||
// NeL includes
|
||||
// #include <nel/misc/debug.h>
|
||||
#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>
|
||||
|
||||
// Project includes
|
||||
|
||||
using namespace std;
|
||||
// using namespace NLMISC;
|
||||
|
||||
namespace NL3D {
|
||||
|
||||
extern const char *g_StereoOVR_fp40; //TODO: what?
|
||||
extern const char *g_StereoOVR_arbfp1; //TODO: what?
|
||||
extern const char *g_StereoOVR_ps_2_0; //TODO: what?
|
||||
|
||||
namespace {
|
||||
sint s_DeviceCounter = 0;
|
||||
};
|
||||
|
||||
class CStereoLibVRDeviceHandle : public IStereoDeviceFactory
|
||||
{
|
||||
public:
|
||||
// fixme: virtual destructor???
|
||||
IStereoDisplay *createDevice() const
|
||||
{
|
||||
CStereoLibVR *stereo = new CStereoLibVR(this);
|
||||
if (stereo->isDeviceCreated())
|
||||
return stereo;
|
||||
delete stereo;
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class CStereoLibVRDevicePtr
|
||||
{
|
||||
public:
|
||||
struct hmd *HMDDevice;
|
||||
struct display_info HMDInfo;
|
||||
float InterpupillaryDistance;
|
||||
};
|
||||
|
||||
CStereoLibVR::CStereoLibVR(const CStereoLibVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL), m_PixelProgram(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f)
|
||||
{
|
||||
struct stereo_config st_conf;
|
||||
|
||||
++s_DeviceCounter;
|
||||
// For now, LibVR doesn't support multiple devices...
|
||||
m_DevicePtr = new CStereoLibVRDevicePtr();
|
||||
m_DevicePtr->HMDDevice = hmd_open_first(0);
|
||||
m_DevicePtr->InterpupillaryDistance = 0.0647; //TODO
|
||||
|
||||
if (m_DevicePtr->HMDDevice)
|
||||
{
|
||||
hmd_get_display_info(m_DevicePtr->HMDDevice, &m_DevicePtr->HMDInfo);
|
||||
hmd_get_stereo_config(m_DevicePtr->HMDDevice, &st_conf);
|
||||
nldebug("LibVR: HScreenSize: %f, VScreenSize: %f", m_DevicePtr->HMDInfo.h_screen_size, m_DevicePtr->HMDInfo.v_screen_size);
|
||||
nldebug("LibVR: VScreenCenter: %f", m_DevicePtr->HMDInfo.v_center);
|
||||
nldebug("LibVR: EyeToScreenDistance: %f", m_DevicePtr->HMDInfo.eye_to_screen[0]);
|
||||
nldebug("LibVR: LensSeparationDistance: %f", m_DevicePtr->HMDInfo.lens_separation);
|
||||
nldebug("LibVR: HResolution: %i, VResolution: %i", m_DevicePtr->HMDInfo.h_resolution, m_DevicePtr->HMDInfo.v_resolution);
|
||||
nldebug("LibVR: DistortionK[0]: %f, DistortionK[1]: %f", m_DevicePtr->HMDInfo.distortion_k[0], m_DevicePtr->HMDInfo.distortion_k[1]);
|
||||
nldebug("LibVR: DistortionK[2]: %f, DistortionK[3]: %f", m_DevicePtr->HMDInfo.distortion_k[2], m_DevicePtr->HMDInfo.distortion_k[3]);
|
||||
nldebug("LibVR: Scale: %f", st_conf.distort.scale);
|
||||
m_LeftViewport.init(0.f, 0.f, 0.5f, 1.0f);
|
||||
m_RightViewport.init(0.5f, 0.f, 0.5f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
CStereoLibVR::~CStereoLibVR()
|
||||
{
|
||||
if (!m_BarrelMat.empty())
|
||||
{
|
||||
m_BarrelMat.getObjectPtr()->setTexture(0, NULL);
|
||||
m_Driver->deleteMaterial(m_BarrelMat);
|
||||
}
|
||||
delete m_BarrelTexU;
|
||||
m_BarrelTexU = NULL;
|
||||
m_BarrelTex = NULL; // CSmartPtr
|
||||
|
||||
delete m_PixelProgram;
|
||||
m_PixelProgram = NULL;
|
||||
|
||||
m_Driver = NULL;
|
||||
|
||||
if (m_DevicePtr->HMDDevice)
|
||||
hmd_close(m_DevicePtr->HMDDevice);
|
||||
|
||||
delete m_DevicePtr;
|
||||
m_DevicePtr = NULL;
|
||||
|
||||
--s_DeviceCounter;
|
||||
}
|
||||
|
||||
void CStereoLibVR::setDriver(NL3D::UDriver *driver)
|
||||
{
|
||||
nlassert(!m_PixelProgram);
|
||||
|
||||
NL3D::IDriver *drvInternal = (static_cast<CDriverUser *>(driver))->getDriver();
|
||||
if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures())
|
||||
{
|
||||
nldebug("VR: fp40");
|
||||
m_PixelProgram = new CPixelProgram(g_StereoOVR_fp40);
|
||||
}
|
||||
else if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures())
|
||||
{
|
||||
nldebug("VR: arbfp1");
|
||||
m_PixelProgram = new CPixelProgram(g_StereoOVR_arbfp1);
|
||||
}
|
||||
else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0))
|
||||
{
|
||||
nldebug("VR: ps_2_0");
|
||||
m_PixelProgram = new CPixelProgram(g_StereoOVR_ps_2_0);
|
||||
}
|
||||
|
||||
if (m_PixelProgram)
|
||||
{
|
||||
m_Driver = driver;
|
||||
|
||||
m_BarrelTex = new CTextureBloom(); // lol bloom
|
||||
m_BarrelTex->setRenderTarget(true);
|
||||
m_BarrelTex->setReleasable(false);
|
||||
m_BarrelTex->resize(m_DevicePtr->HMDInfo.h_resolution, m_DevicePtr->HMDInfo.v_resolution);
|
||||
m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff);
|
||||
m_BarrelTex->setWrapS(ITexture::Clamp);
|
||||
m_BarrelTex->setWrapT(ITexture::Clamp);
|
||||
drvInternal->setupTexture(*m_BarrelTex);
|
||||
m_BarrelTexU = new CTextureUser(m_BarrelTex);
|
||||
|
||||
m_BarrelMat = m_Driver->createMaterial();
|
||||
m_BarrelMat.initUnlit();
|
||||
m_BarrelMat.setColor(CRGBA::White);
|
||||
m_BarrelMat.setBlend (false);
|
||||
m_BarrelMat.setAlphaTest (false);
|
||||
NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr();
|
||||
barrelMat->setShader(NL3D::CMaterial::PostProcessing);
|
||||
barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero);
|
||||
barrelMat->setZWrite(false);
|
||||
barrelMat->setZFunc(CMaterial::always);
|
||||
barrelMat->setDoubleSided(true);
|
||||
barrelMat->setTexture(0, m_BarrelTex);
|
||||
|
||||
m_BarrelQuadLeft.V0 = CVector(0.f, 0.f, 0.5f);
|
||||
m_BarrelQuadLeft.V1 = CVector(0.5f, 0.f, 0.5f);
|
||||
m_BarrelQuadLeft.V2 = CVector(0.5f, 1.f, 0.5f);
|
||||
m_BarrelQuadLeft.V3 = CVector(0.f, 1.f, 0.5f);
|
||||
|
||||
m_BarrelQuadRight.V0 = CVector(0.5f, 0.f, 0.5f);
|
||||
m_BarrelQuadRight.V1 = CVector(1.f, 0.f, 0.5f);
|
||||
m_BarrelQuadRight.V2 = CVector(1.f, 1.f, 0.5f);
|
||||
m_BarrelQuadRight.V3 = CVector(0.5f, 1.f, 0.5f);
|
||||
|
||||
nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // not allowed
|
||||
|
||||
m_BarrelQuadLeft.Uv0 = CUV(0.f, 0.f);
|
||||
m_BarrelQuadLeft.Uv1 = CUV(0.5f, 0.f);
|
||||
m_BarrelQuadLeft.Uv2 = CUV(0.5f, 1.f);
|
||||
m_BarrelQuadLeft.Uv3 = CUV(0.f, 1.f);
|
||||
|
||||
m_BarrelQuadRight.Uv0 = CUV(0.5f, 0.f);
|
||||
m_BarrelQuadRight.Uv1 = CUV(1.f, 0.f);
|
||||
m_BarrelQuadRight.Uv2 = CUV(1.f, 1.f);
|
||||
m_BarrelQuadRight.Uv3 = CUV(0.5f, 1.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
nlwarning("VR: No pixel program support");
|
||||
}
|
||||
}
|
||||
|
||||
bool CStereoLibVR::getScreenResolution(uint &width, uint &height)
|
||||
{
|
||||
width = m_DevicePtr->HMDInfo.h_resolution;
|
||||
height = m_DevicePtr->HMDInfo.v_resolution;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CStereoLibVR::initCamera(uint cid, const NL3D::UCamera *camera)
|
||||
{
|
||||
struct stereo_config st_conf;
|
||||
hmd_get_stereo_config(m_DevicePtr->HMDDevice, &st_conf);
|
||||
|
||||
float ar = st_conf.proj.aspect_ratio;
|
||||
float fov = st_conf.proj.yfov;
|
||||
m_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far);
|
||||
m_RightFrustum[cid] = m_LeftFrustum[cid];
|
||||
|
||||
float projectionCenterOffset = st_conf.proj.projection_offset * 0.5 * (m_LeftFrustum[cid].Right - m_LeftFrustum[cid].Left);
|
||||
nldebug("LibVR: projectionCenterOffset = %f", projectionCenterOffset);
|
||||
|
||||
m_LeftFrustum[cid].Left -= projectionCenterOffset;
|
||||
m_LeftFrustum[cid].Right -= projectionCenterOffset;
|
||||
m_RightFrustum[cid].Left += projectionCenterOffset;
|
||||
m_RightFrustum[cid].Right += projectionCenterOffset;
|
||||
|
||||
// TODO: Clipping frustum should also take into account the IPD
|
||||
m_ClippingFrustum[cid] = m_LeftFrustum[cid];
|
||||
m_ClippingFrustum[cid].Left = min(m_LeftFrustum[cid].Left, m_RightFrustum[cid].Left);
|
||||
m_ClippingFrustum[cid].Right = max(m_LeftFrustum[cid].Right, m_RightFrustum[cid].Right);
|
||||
}
|
||||
|
||||
/// Get the frustum to use for clipping
|
||||
void CStereoLibVR::getClippingFrustum(uint cid, NL3D::UCamera *camera) const
|
||||
{
|
||||
camera->setFrustum(m_ClippingFrustum[cid]);
|
||||
}
|
||||
|
||||
void CStereoLibVR::updateCamera(uint cid, const NL3D::UCamera *camera)
|
||||
{
|
||||
if (camera->getFrustum().Near != m_LeftFrustum[cid].Near
|
||||
|| camera->getFrustum().Far != m_LeftFrustum[cid].Far)
|
||||
CStereoLibVR::initCamera(cid, camera);
|
||||
m_CameraMatrix[cid] = camera->getMatrix();
|
||||
}
|
||||
|
||||
bool CStereoLibVR::nextPass()
|
||||
{
|
||||
// Do not allow weird stuff.
|
||||
uint32 width, height;
|
||||
m_Driver->getWindowSize(width, height);
|
||||
nlassert(width == m_DevicePtr->HMDInfo.h_resolution);
|
||||
nlassert(height == m_DevicePtr->HMDInfo.v_resolution);
|
||||
|
||||
if (m_Driver->getPolygonMode() == UDriver::Filled)
|
||||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case 0:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
// stage 1:
|
||||
// (initBloom)
|
||||
// clear buffer
|
||||
// draw scene left
|
||||
return true;
|
||||
case 1:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
// stage 2:
|
||||
// draw scene right
|
||||
return true;
|
||||
case 2:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
// stage 3:
|
||||
// (endBloom)
|
||||
// draw interface 3d left
|
||||
return true;
|
||||
case 3:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
// stage 4:
|
||||
// draw interface 3d right
|
||||
return true;
|
||||
case 4:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
// stage 5:
|
||||
// (endInterfacesDisplayBloom)
|
||||
// draw interface 2d left
|
||||
return true;
|
||||
case 5:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
// stage 6:
|
||||
// draw interface 2d right
|
||||
return true;
|
||||
case 6:
|
||||
m_Stage = 0;
|
||||
m_SubStage = 0;
|
||||
// present
|
||||
m_OrientationCached = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case 0:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
return true;
|
||||
case 1:
|
||||
m_Stage = 0;
|
||||
m_SubStage = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
nlerror("Invalid stage");
|
||||
m_Stage = 0;
|
||||
m_SubStage = 0;
|
||||
m_OrientationCached = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
const NL3D::CViewport &CStereoLibVR::getCurrentViewport() const
|
||||
{
|
||||
if (m_Stage % 2) return m_LeftViewport;
|
||||
else return m_RightViewport;
|
||||
}
|
||||
|
||||
const NL3D::CFrustum &CStereoLibVR::getCurrentFrustum(uint cid) const
|
||||
{
|
||||
if (m_Stage % 2) return m_LeftFrustum[cid];
|
||||
else return m_RightFrustum[cid];
|
||||
}
|
||||
|
||||
void CStereoLibVR::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const
|
||||
{
|
||||
if (m_Stage % 2) camera->setFrustum(m_LeftFrustum[cid]);
|
||||
else camera->setFrustum(m_RightFrustum[cid]);
|
||||
}
|
||||
|
||||
void CStereoLibVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const
|
||||
{
|
||||
CMatrix translate;
|
||||
if (m_Stage % 2) translate.translate(CVector((m_DevicePtr->InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f));
|
||||
else translate.translate(CVector((m_DevicePtr->InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f));
|
||||
CMatrix mat = m_CameraMatrix[cid] * translate;
|
||||
if (camera->getTransformMode() == NL3D::UTransformable::RotQuat)
|
||||
{
|
||||
camera->setPos(mat.getPos());
|
||||
camera->setRotQuat(mat.getRot());
|
||||
}
|
||||
else
|
||||
{
|
||||
// camera->setTransformMode(NL3D::UTransformable::DirectMatrix);
|
||||
camera->setMatrix(mat);
|
||||
}
|
||||
}
|
||||
|
||||
bool CStereoLibVR::wantClear()
|
||||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case 1:
|
||||
m_SubStage = 1;
|
||||
return true;
|
||||
}
|
||||
return m_Driver->getPolygonMode() != UDriver::Filled;
|
||||
}
|
||||
|
||||
bool CStereoLibVR::wantScene()
|
||||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
m_SubStage = 2;
|
||||
return true;
|
||||
}
|
||||
return m_Driver->getPolygonMode() != UDriver::Filled;
|
||||
}
|
||||
|
||||
bool CStereoLibVR::wantInterface3D()
|
||||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case 3:
|
||||
case 4:
|
||||
m_SubStage = 3;
|
||||
return true;
|
||||
}
|
||||
return m_Driver->getPolygonMode() != UDriver::Filled;
|
||||
}
|
||||
|
||||
bool CStereoLibVR::wantInterface2D()
|
||||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case 5:
|
||||
case 6:
|
||||
m_SubStage = 4;
|
||||
return true;
|
||||
}
|
||||
return m_Driver->getPolygonMode() != UDriver::Filled;
|
||||
}
|
||||
|
||||
|
||||
/// Returns non-NULL if a new render target was set
|
||||
bool CStereoLibVR::beginRenderTarget()
|
||||
{
|
||||
// render target always set before driver clear
|
||||
// nlassert(m_SubStage <= 1);
|
||||
if (m_Driver && m_Stage == 1 && (m_Driver->getPolygonMode() == UDriver::Filled))
|
||||
{
|
||||
static_cast<CDriverUser *>(m_Driver)->setRenderTarget(*m_BarrelTexU, 0, 0, 0, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns true if a render target was fully drawn
|
||||
bool CStereoLibVR::endRenderTarget()
|
||||
{
|
||||
// after rendering of course
|
||||
// nlassert(m_SubStage > 1);
|
||||
if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui
|
||||
{
|
||||
struct stereo_config st_conf;
|
||||
hmd_get_stereo_config(m_DevicePtr->HMDDevice, &st_conf);
|
||||
CTextureUser cu;
|
||||
(static_cast<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;
|
||||
m_Driver->getWindowSize(width, height);
|
||||
NL3D::IDriver *drvInternal = (static_cast<CDriverUser *>(m_Driver))->getDriver();
|
||||
NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr();
|
||||
barrelMat->setTexture(0, m_BarrelTex);
|
||||
drvInternal->activePixelProgram(m_PixelProgram);
|
||||
|
||||
float w = float(m_BarrelQuadLeft.V1.x),// / float(width),
|
||||
h = float(m_BarrelQuadLeft.V2.y),// / float(height),
|
||||
x = float(m_BarrelQuadLeft.V0.x),/// / float(width),
|
||||
y = float(m_BarrelQuadLeft.V0.y);// / float(height);
|
||||
|
||||
//TODO: stereo_config stuff
|
||||
float lensViewportShift = st_conf.proj.projection_offset;
|
||||
|
||||
float lensCenterX = x + (w + lensViewportShift * 0.5f) * 0.5f;
|
||||
float lensCenterY = y + h * 0.5f;
|
||||
float screenCenterX = x + w * 0.5f;
|
||||
float screenCenterY = y + h * 0.5f;
|
||||
float scaleX = (w / 2 / st_conf.distort.scale);
|
||||
float scaleY = (h / 2 / st_conf.distort.scale);
|
||||
float scaleInX = (2 / w);
|
||||
float scaleInY = (2 / h);
|
||||
drvInternal->setPixelProgramConstant(0, lensCenterX, lensCenterY, 0.f, 0.f);
|
||||
drvInternal->setPixelProgramConstant(1, screenCenterX, screenCenterY, 0.f, 0.f);
|
||||
drvInternal->setPixelProgramConstant(2, scaleX, scaleY, 0.f, 0.f);
|
||||
drvInternal->setPixelProgramConstant(3, scaleInX, scaleInY, 0.f, 0.f);
|
||||
drvInternal->setPixelProgramConstant(4, 1, st_conf.distort.distortion_k);
|
||||
|
||||
|
||||
m_Driver->drawQuad(m_BarrelQuadLeft, m_BarrelMat);
|
||||
|
||||
x = w;
|
||||
lensCenterX = x + (w - lensViewportShift * 0.5f) * 0.5f;
|
||||
screenCenterX = x + w * 0.5f;
|
||||
drvInternal->setPixelProgramConstant(0, lensCenterX, lensCenterY, 0.f, 0.f);
|
||||
drvInternal->setPixelProgramConstant(1, screenCenterX, screenCenterY, 0.f, 0.f);
|
||||
|
||||
m_Driver->drawQuad(m_BarrelQuadRight, m_BarrelMat);
|
||||
|
||||
drvInternal->activePixelProgram(NULL);
|
||||
m_Driver->enableFog(fogEnabled);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NLMISC::CQuat CStereoLibVR::getOrientation() const
|
||||
{
|
||||
if (m_OrientationCached)
|
||||
return m_OrientationCache;
|
||||
|
||||
unsigned int t = NLMISC::CTime::getLocalTime();
|
||||
hmd_update(m_DevicePtr->HMDDevice, &t);
|
||||
|
||||
float quat[4];
|
||||
hmd_get_rotation(m_DevicePtr->HMDDevice, quat);
|
||||
NLMISC::CMatrix coordsys;
|
||||
float csys[] = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, -1.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f,
|
||||
};
|
||||
coordsys.set(csys);
|
||||
NLMISC::CMatrix matovr;
|
||||
matovr.setRot(NLMISC::CQuat(quat[1], quat[2], quat[3], quat[0]));
|
||||
NLMISC::CMatrix matr;
|
||||
matr.rotateX(NLMISC::Pi * 0.5f); // fix this properly... :) (note: removing this allows you to use rift while lying down)
|
||||
NLMISC::CMatrix matnel = matr * matovr * coordsys;
|
||||
NLMISC::CQuat finalquat = matnel.getRot();
|
||||
m_OrientationCache = finalquat;
|
||||
m_OrientationCached = true;
|
||||
return finalquat;
|
||||
}
|
||||
|
||||
/// Get GUI shift
|
||||
void CStereoLibVR::getInterface2DShift(uint cid, float &x, float &y, float distance) const
|
||||
{
|
||||
#if 0
|
||||
|
||||
// todo: take into account m_EyePosition
|
||||
|
||||
NLMISC::CVector vector = CVector(0.f, -distance, 0.f);
|
||||
NLMISC::CQuat rot = getOrientation();
|
||||
rot.invert();
|
||||
NLMISC::CMatrix mat;
|
||||
mat.rotate(rot);
|
||||
//if (m_Stage % 2) mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f));
|
||||
//else mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f));
|
||||
mat.translate(vector);
|
||||
CVector proj = CStereoOVR::getCurrentFrustum(cid).project(mat.getPos());
|
||||
|
||||
NLMISC::CVector ipd;
|
||||
if (m_Stage % 2) ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f);
|
||||
else ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f);
|
||||
CVector projipd = CStereoOVR::getCurrentFrustum(cid).project(vector + ipd);
|
||||
CVector projvec = CStereoOVR::getCurrentFrustum(cid).project(vector);
|
||||
|
||||
x = (proj.x + projipd.x - projvec.x - 0.5f);
|
||||
y = (proj.y + projipd.y - projvec.y - 0.5f);
|
||||
|
||||
#elif 1
|
||||
|
||||
// Alternative method
|
||||
// todo: take into account m_EyePosition
|
||||
|
||||
NLMISC::CVector vec = CVector(0.f, -distance, 0.f);
|
||||
NLMISC::CVector ipd;
|
||||
if (m_Stage % 2) ipd = CVector((m_DevicePtr->InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f);
|
||||
else ipd = CVector((m_DevicePtr->InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f);
|
||||
|
||||
|
||||
NLMISC::CQuat rot = getOrientation();
|
||||
NLMISC::CQuat modrot = NLMISC::CQuat(CVector(0.f, 1.f, 0.f), NLMISC::Pi);
|
||||
rot = rot * modrot;
|
||||
float p = NLMISC::Pi + atan2f(2.0f * ((rot.x * rot.y) + (rot.z * rot.w)), 1.0f - 2.0f * ((rot.y * rot.y) + (rot.w * rot.w)));
|
||||
if (p > NLMISC::Pi) p -= NLMISC::Pi * 2.0f;
|
||||
float t = -atan2f(2.0f * ((rot.x * rot.w) + (rot.y * rot.z)), 1.0f - 2.0f * ((rot.z * rot.z) + (rot.w * rot.w)));// // asinf(2.0f * ((rot.x * rot.z) - (rot.w * rot.y)));
|
||||
|
||||
CVector rotshift = CVector(p, 0.f, t) * -distance;
|
||||
|
||||
CVector proj = CStereoLibVR::getCurrentFrustum(cid).project(vec + ipd + rotshift);
|
||||
|
||||
x = (proj.x - 0.5f);
|
||||
y = (proj.y - 0.5f);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void CStereoLibVR::setEyePosition(const NLMISC::CVector &v)
|
||||
{
|
||||
m_EyePosition = v;
|
||||
}
|
||||
|
||||
const NLMISC::CVector &CStereoLibVR::getEyePosition() const
|
||||
{
|
||||
return m_EyePosition;
|
||||
}
|
||||
|
||||
void CStereoLibVR::setScale(float s)
|
||||
{
|
||||
m_EyePosition = m_EyePosition * (s / m_Scale);
|
||||
m_Scale = s;
|
||||
}
|
||||
|
||||
void CStereoLibVR::listDevices(std::vector<CStereoDeviceInfo> &devicesOut)
|
||||
{
|
||||
// For now, LibVR doesn't support multiple devices
|
||||
struct hmd *hmd = hmd_open_first(0);
|
||||
if (hmd)
|
||||
{
|
||||
CStereoDeviceInfo deviceInfoOut;
|
||||
CStereoLibVRDeviceHandle *handle = new CStereoLibVRDeviceHandle();
|
||||
deviceInfoOut.Factory = static_cast<IStereoDeviceFactory *>(handle);
|
||||
deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD;
|
||||
deviceInfoOut.Library = CStereoDeviceInfo::LibVR;
|
||||
//TODO: manufacturer, produc name
|
||||
//TODO: serial
|
||||
devicesOut.push_back(deviceInfoOut);
|
||||
hmd_close(hmd);
|
||||
}
|
||||
}
|
||||
|
||||
bool CStereoLibVR::isLibraryInUse()
|
||||
{
|
||||
nlassert(s_DeviceCounter >= 0);
|
||||
return s_DeviceCounter > 0;
|
||||
}
|
||||
|
||||
void CStereoLibVR::releaseLibrary()
|
||||
{
|
||||
nlassert(s_DeviceCounter == 0);
|
||||
}
|
||||
|
||||
bool CStereoLibVR::isDeviceCreated()
|
||||
{
|
||||
return m_DevicePtr->HMDDevice != NULL;
|
||||
}
|
||||
|
||||
} /* namespace NL3D */
|
||||
|
||||
#endif /* HAVE_LIBVR */
|
||||
|
||||
/* end of file */
|
850
code/nel/src/3d/stereo_ovr.cpp
Normal file
850
code/nel/src/3d/stereo_ovr.cpp
Normal file
|
@ -0,0 +1,850 @@
|
|||
/**
|
||||
* \file stereo_ovr.cpp
|
||||
* \brief CStereoOVR
|
||||
* \date 2013-06-25 22:22GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* CStereoOVR
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 by authors
|
||||
*
|
||||
* This file is part of NL3D.
|
||||
* NL3D is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* NL3D is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with NL3D. If not, see
|
||||
* <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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_LIBOVR
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include <nel/3d/stereo_ovr.h>
|
||||
|
||||
// STL includes
|
||||
#include <sstream>
|
||||
|
||||
// External includes
|
||||
#include <OVR.h>
|
||||
|
||||
// NeL includes
|
||||
// #include <nel/misc/debug.h>
|
||||
#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>
|
||||
|
||||
// Project includes
|
||||
|
||||
using namespace std;
|
||||
// using namespace NLMISC;
|
||||
|
||||
namespace NL3D {
|
||||
|
||||
extern const char *g_StereoOVR_fp40;
|
||||
extern const char *g_StereoOVR_arbfp1;
|
||||
extern const char *g_StereoOVR_ps_2_0;
|
||||
extern const char *g_StereoOVR_glsl330f;
|
||||
|
||||
namespace {
|
||||
|
||||
class CStereoOVRLog : public OVR::Log
|
||||
{
|
||||
public:
|
||||
CStereoOVRLog(unsigned logMask = OVR::LogMask_All) : OVR::Log(logMask)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void LogMessageVarg(OVR::LogMessageType messageType, const char* fmt, va_list argList)
|
||||
{
|
||||
if (NLMISC::INelContext::isContextInitialised())
|
||||
{
|
||||
char buffer[MaxLogBufferMessageSize];
|
||||
FormatLog(buffer, MaxLogBufferMessageSize, messageType, fmt, argList);
|
||||
if (IsDebugMessage(messageType))
|
||||
NLMISC::INelContext::getInstance().getDebugLog()->displayNL("OVR: %s", buffer);
|
||||
else
|
||||
NLMISC::INelContext::getInstance().getInfoLog()->displayNL("OVR: %s", buffer);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CStereoOVRLog *s_StereoOVRLog = NULL;
|
||||
OVR::Ptr<OVR::DeviceManager> s_DeviceManager;
|
||||
|
||||
class CStereoOVRSystem
|
||||
{
|
||||
public:
|
||||
~CStereoOVRSystem()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
if (!s_StereoOVRLog)
|
||||
{
|
||||
nldebug("Initialize OVR");
|
||||
s_StereoOVRLog = new CStereoOVRLog();
|
||||
}
|
||||
if (!OVR::System::IsInitialized())
|
||||
OVR::System::Init(s_StereoOVRLog);
|
||||
if (!s_DeviceManager)
|
||||
s_DeviceManager = OVR::DeviceManager::Create();
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
if (s_DeviceManager)
|
||||
{
|
||||
nldebug("Release OVR");
|
||||
s_DeviceManager->Release();
|
||||
}
|
||||
s_DeviceManager.Clear();
|
||||
if (OVR::System::IsInitialized())
|
||||
OVR::System::Destroy();
|
||||
if (s_StereoOVRLog)
|
||||
nldebug("Release OVR Ok");
|
||||
delete s_StereoOVRLog;
|
||||
s_StereoOVRLog = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
CStereoOVRSystem s_StereoOVRSystem;
|
||||
|
||||
sint s_DeviceCounter = 0;
|
||||
|
||||
}
|
||||
|
||||
class CStereoOVRDeviceHandle : public IStereoDeviceFactory
|
||||
{
|
||||
public:
|
||||
// fixme: virtual destructor???
|
||||
OVR::DeviceEnumerator<OVR::HMDDevice> DeviceHandle;
|
||||
IStereoDisplay *createDevice() const
|
||||
{
|
||||
CStereoOVR *stereo = new CStereoOVR(this);
|
||||
if (stereo->isDeviceCreated())
|
||||
return stereo;
|
||||
delete stereo;
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class CStereoOVRDevicePtr
|
||||
{
|
||||
public:
|
||||
OVR::Ptr<OVR::HMDDevice> HMDDevice;
|
||||
OVR::Ptr<OVR::SensorDevice> SensorDevice;
|
||||
OVR::SensorFusion SensorFusion;
|
||||
OVR::HMDInfo HMDInfo;
|
||||
};
|
||||
|
||||
CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL), m_PixelProgram(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f)
|
||||
{
|
||||
++s_DeviceCounter;
|
||||
m_DevicePtr = new CStereoOVRDevicePtr();
|
||||
|
||||
OVR::DeviceEnumerator<OVR::HMDDevice> dh = handle->DeviceHandle;
|
||||
m_DevicePtr->HMDDevice = dh.CreateDevice();
|
||||
|
||||
if (m_DevicePtr->HMDDevice)
|
||||
{
|
||||
m_DevicePtr->HMDDevice->GetDeviceInfo(&m_DevicePtr->HMDInfo);
|
||||
nldebug("OVR: HScreenSize: %f, VScreenSize: %f", m_DevicePtr->HMDInfo.HScreenSize, m_DevicePtr->HMDInfo.VScreenSize);
|
||||
nldebug("OVR: VScreenCenter: %f", m_DevicePtr->HMDInfo.VScreenCenter);
|
||||
nldebug("OVR: EyeToScreenDistance: %f", m_DevicePtr->HMDInfo.EyeToScreenDistance);
|
||||
nldebug("OVR: LensSeparationDistance: %f", m_DevicePtr->HMDInfo.LensSeparationDistance);
|
||||
nldebug("OVR: InterpupillaryDistance: %f", m_DevicePtr->HMDInfo.InterpupillaryDistance);
|
||||
nldebug("OVR: HResolution: %i, VResolution: %i", m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution);
|
||||
nldebug("OVR: DistortionK[0]: %f, DistortionK[1]: %f", m_DevicePtr->HMDInfo.DistortionK[0], m_DevicePtr->HMDInfo.DistortionK[1]);
|
||||
nldebug("OVR: DistortionK[2]: %f, DistortionK[3]: %f", m_DevicePtr->HMDInfo.DistortionK[2], m_DevicePtr->HMDInfo.DistortionK[3]);
|
||||
//2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 160 NL3D::CStereoOVR::CStereoOVR : OVR: HScreenSize: 0.149760, VScreenSize: 0.093600
|
||||
//2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 161 NL3D::CStereoOVR::CStereoOVR : OVR: VScreenCenter: 0.046800
|
||||
//2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 162 NL3D::CStereoOVR::CStereoOVR : OVR: EyeToScreenDistance: 0.041000
|
||||
//2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 163 NL3D::CStereoOVR::CStereoOVR : OVR: LensSeparationDistance: 0.063500
|
||||
//2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 164 NL3D::CStereoOVR::CStereoOVR : OVR: InterpupillaryDistance: 0.064000
|
||||
//2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 165 NL3D::CStereoOVR::CStereoOVR : OVR: HResolution: 1280, VResolution: 800
|
||||
//2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 166 NL3D::CStereoOVR::CStereoOVR : OVR: DistortionK[0]: 1.000000, DistortionK[1]: 0.220000
|
||||
//2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 167 NL3D::CStereoOVR::CStereoOVR : OVR: DistortionK[2]: 0.240000, DistortionK[3]: 0.000000
|
||||
m_DevicePtr->SensorDevice = m_DevicePtr->HMDDevice->GetSensor();
|
||||
m_DevicePtr->SensorFusion.AttachToSensor(m_DevicePtr->SensorDevice);
|
||||
m_DevicePtr->SensorFusion.SetGravityEnabled(true);
|
||||
m_DevicePtr->SensorFusion.SetPredictionEnabled(true);
|
||||
m_DevicePtr->SensorFusion.SetYawCorrectionEnabled(true);
|
||||
m_LeftViewport.init(0.f, 0.f, 0.5f, 1.0f);
|
||||
m_RightViewport.init(0.5f, 0.f, 0.5f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
CStereoOVR::~CStereoOVR()
|
||||
{
|
||||
if (!m_BarrelMat.empty())
|
||||
{
|
||||
m_BarrelMat.getObjectPtr()->setTexture(0, NULL);
|
||||
m_Driver->deleteMaterial(m_BarrelMat);
|
||||
}
|
||||
delete m_BarrelTexU;
|
||||
m_BarrelTexU = NULL;
|
||||
m_BarrelTex = NULL; // CSmartPtr
|
||||
|
||||
delete m_PixelProgram;
|
||||
m_PixelProgram = NULL;
|
||||
|
||||
m_Driver = NULL;
|
||||
|
||||
if (m_DevicePtr->SensorDevice)
|
||||
m_DevicePtr->SensorDevice->Release();
|
||||
m_DevicePtr->SensorDevice.Clear();
|
||||
if (m_DevicePtr->HMDDevice)
|
||||
m_DevicePtr->HMDDevice->Release();
|
||||
m_DevicePtr->HMDDevice.Clear();
|
||||
|
||||
delete m_DevicePtr;
|
||||
m_DevicePtr = NULL;
|
||||
--s_DeviceCounter;
|
||||
}
|
||||
|
||||
class CPixelProgramOVR : public CPixelProgram
|
||||
{
|
||||
public:
|
||||
struct COVRIndices
|
||||
{
|
||||
uint LensCenter;
|
||||
uint ScreenCenter;
|
||||
uint Scale;
|
||||
uint ScaleIn;
|
||||
uint HmdWarpParam;
|
||||
};
|
||||
|
||||
CPixelProgramOVR()
|
||||
{
|
||||
{
|
||||
CSource *source = new CSource();
|
||||
source->Profile = glsl330f;
|
||||
source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages;
|
||||
source->setSourcePtr(g_StereoOVR_glsl330f);
|
||||
addSource(source);
|
||||
}
|
||||
{
|
||||
CSource *source = new CSource();
|
||||
source->Profile = fp40;
|
||||
source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages;
|
||||
source->setSourcePtr(g_StereoOVR_fp40);
|
||||
source->ParamIndices["cLensCenter"] = 0;
|
||||
source->ParamIndices["cScreenCenter"] = 1;
|
||||
source->ParamIndices["cScale"] = 2;
|
||||
source->ParamIndices["cScaleIn"] = 3;
|
||||
source->ParamIndices["cHmdWarpParam"] = 4;
|
||||
addSource(source);
|
||||
}
|
||||
{
|
||||
CSource *source = new CSource();
|
||||
source->Profile = arbfp1;
|
||||
source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages;
|
||||
source->setSourcePtr(g_StereoOVR_arbfp1);
|
||||
source->ParamIndices["cLensCenter"] = 0;
|
||||
source->ParamIndices["cScreenCenter"] = 1;
|
||||
source->ParamIndices["cScale"] = 2;
|
||||
source->ParamIndices["cScaleIn"] = 3;
|
||||
source->ParamIndices["cHmdWarpParam"] = 4;
|
||||
addSource(source);
|
||||
}
|
||||
{
|
||||
CSource *source = new CSource();
|
||||
source->Profile = ps_2_0;
|
||||
source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages;
|
||||
source->setSourcePtr(g_StereoOVR_ps_2_0);
|
||||
source->ParamIndices["cLensCenter"] = 0;
|
||||
source->ParamIndices["cScreenCenter"] = 1;
|
||||
source->ParamIndices["cScale"] = 2;
|
||||
source->ParamIndices["cScaleIn"] = 3;
|
||||
source->ParamIndices["cHmdWarpParam"] = 4;
|
||||
addSource(source);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~CPixelProgramOVR()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void buildInfo()
|
||||
{
|
||||
CPixelProgram::buildInfo();
|
||||
|
||||
m_OVRIndices.LensCenter = getUniformIndex("cLensCenter");
|
||||
nlassert(m_OVRIndices.LensCenter != ~0);
|
||||
m_OVRIndices.ScreenCenter = getUniformIndex("cScreenCenter");
|
||||
nlassert(m_OVRIndices.ScreenCenter != ~0);
|
||||
m_OVRIndices.Scale = getUniformIndex("cScale");
|
||||
nlassert(m_OVRIndices.Scale != ~0);
|
||||
m_OVRIndices.ScaleIn = getUniformIndex("cScaleIn");
|
||||
nlassert(m_OVRIndices.ScaleIn != ~0);
|
||||
m_OVRIndices.HmdWarpParam = getUniformIndex("cHmdWarpParam");
|
||||
nlassert(m_OVRIndices.HmdWarpParam != ~0);
|
||||
}
|
||||
|
||||
inline const COVRIndices &ovrIndices() { return m_OVRIndices; }
|
||||
|
||||
private:
|
||||
COVRIndices m_OVRIndices;
|
||||
|
||||
};
|
||||
|
||||
void CStereoOVR::setDriver(NL3D::UDriver *driver)
|
||||
{
|
||||
nlassert(!m_PixelProgram);
|
||||
|
||||
NL3D::IDriver *drvInternal = (static_cast<CDriverUser *>(driver))->getDriver();
|
||||
|
||||
if (drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures())
|
||||
{
|
||||
m_PixelProgram = new CPixelProgramOVR();
|
||||
if (!drvInternal->compilePixelProgram(m_PixelProgram))
|
||||
{
|
||||
m_PixelProgram.kill();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_PixelProgram)
|
||||
{
|
||||
m_Driver = driver;
|
||||
|
||||
m_BarrelTex = new CTextureBloom(); // lol bloom
|
||||
m_BarrelTex->setRenderTarget(true);
|
||||
m_BarrelTex->setReleasable(false);
|
||||
m_BarrelTex->resize(m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution);
|
||||
m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff);
|
||||
m_BarrelTex->setWrapS(ITexture::Clamp);
|
||||
m_BarrelTex->setWrapT(ITexture::Clamp);
|
||||
drvInternal->setupTexture(*m_BarrelTex);
|
||||
m_BarrelTexU = new CTextureUser(m_BarrelTex);
|
||||
|
||||
m_BarrelMat = m_Driver->createMaterial();
|
||||
m_BarrelMat.initUnlit();
|
||||
m_BarrelMat.setColor(CRGBA::White);
|
||||
m_BarrelMat.setBlend (false);
|
||||
m_BarrelMat.setAlphaTest (false);
|
||||
NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr();
|
||||
barrelMat->setShader(NL3D::CMaterial::Normal);
|
||||
barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero);
|
||||
barrelMat->setZWrite(false);
|
||||
barrelMat->setZFunc(CMaterial::always);
|
||||
barrelMat->setDoubleSided(true);
|
||||
barrelMat->setTexture(0, m_BarrelTex);
|
||||
|
||||
m_BarrelQuadLeft.V0 = CVector(0.f, 0.f, 0.5f);
|
||||
m_BarrelQuadLeft.V1 = CVector(0.5f, 0.f, 0.5f);
|
||||
m_BarrelQuadLeft.V2 = CVector(0.5f, 1.f, 0.5f);
|
||||
m_BarrelQuadLeft.V3 = CVector(0.f, 1.f, 0.5f);
|
||||
|
||||
m_BarrelQuadRight.V0 = CVector(0.5f, 0.f, 0.5f);
|
||||
m_BarrelQuadRight.V1 = CVector(1.f, 0.f, 0.5f);
|
||||
m_BarrelQuadRight.V2 = CVector(1.f, 1.f, 0.5f);
|
||||
m_BarrelQuadRight.V3 = CVector(0.5f, 1.f, 0.5f);
|
||||
|
||||
nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // not allowed
|
||||
|
||||
m_BarrelQuadLeft.Uv0 = CUV(0.f, 0.f);
|
||||
m_BarrelQuadLeft.Uv1 = CUV(0.5f, 0.f);
|
||||
m_BarrelQuadLeft.Uv2 = CUV(0.5f, 1.f);
|
||||
m_BarrelQuadLeft.Uv3 = CUV(0.f, 1.f);
|
||||
|
||||
m_BarrelQuadRight.Uv0 = CUV(0.5f, 0.f);
|
||||
m_BarrelQuadRight.Uv1 = CUV(1.f, 0.f);
|
||||
m_BarrelQuadRight.Uv2 = CUV(1.f, 1.f);
|
||||
m_BarrelQuadRight.Uv3 = CUV(0.5f, 1.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
nlwarning("VR: No pixel program support");
|
||||
}
|
||||
}
|
||||
|
||||
bool CStereoOVR::getScreenResolution(uint &width, uint &height)
|
||||
{
|
||||
width = m_DevicePtr->HMDInfo.HResolution;
|
||||
height = m_DevicePtr->HMDInfo.VResolution;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera)
|
||||
{
|
||||
float ar = (float)m_DevicePtr->HMDInfo.HResolution / ((float)m_DevicePtr->HMDInfo.VResolution * 2.0f);
|
||||
float fov = 2.0f * atanf((m_DevicePtr->HMDInfo.HScreenSize * 0.5f * 0.5f) / (m_DevicePtr->HMDInfo.EyeToScreenDistance)); //(float)NLMISC::Pi/2.f; // 2.0f * atanf(m_DevicePtr->HMDInfo.VScreenSize / 2.0f * m_DevicePtr->HMDInfo.EyeToScreenDistance);
|
||||
m_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far);
|
||||
m_RightFrustum[cid] = m_LeftFrustum[cid];
|
||||
|
||||
float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f;
|
||||
float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; // docs say LensSeparationDistance, why not InterpupillaryDistance? related to how the lenses work?
|
||||
float projectionCenterOffset = (eyeProjectionShift / (m_DevicePtr->HMDInfo.HScreenSize * 0.5f)) * (m_LeftFrustum[cid].Right - m_LeftFrustum[cid].Left); // used logic for this one, but it ends up being the same as the one i made up
|
||||
nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset);
|
||||
|
||||
m_LeftFrustum[cid].Left -= projectionCenterOffset;
|
||||
m_LeftFrustum[cid].Right -= projectionCenterOffset;
|
||||
m_RightFrustum[cid].Left += projectionCenterOffset;
|
||||
m_RightFrustum[cid].Right += projectionCenterOffset;
|
||||
|
||||
// TODO: Clipping frustum should also take into account the IPD
|
||||
m_ClippingFrustum[cid] = m_LeftFrustum[cid];
|
||||
m_ClippingFrustum[cid].Left = min(m_LeftFrustum[cid].Left, m_RightFrustum[cid].Left);
|
||||
m_ClippingFrustum[cid].Right = max(m_LeftFrustum[cid].Right, m_RightFrustum[cid].Right);
|
||||
}
|
||||
|
||||
/// Get the frustum to use for clipping
|
||||
void CStereoOVR::getClippingFrustum(uint cid, NL3D::UCamera *camera) const
|
||||
{
|
||||
camera->setFrustum(m_ClippingFrustum[cid]);
|
||||
}
|
||||
|
||||
void CStereoOVR::updateCamera(uint cid, const NL3D::UCamera *camera)
|
||||
{
|
||||
if (camera->getFrustum().Near != m_LeftFrustum[cid].Near
|
||||
|| camera->getFrustum().Far != m_LeftFrustum[cid].Far)
|
||||
CStereoOVR::initCamera(cid, camera);
|
||||
m_CameraMatrix[cid] = camera->getMatrix();
|
||||
}
|
||||
|
||||
bool CStereoOVR::nextPass()
|
||||
{
|
||||
// Do not allow weird stuff.
|
||||
uint32 width, height;
|
||||
m_Driver->getWindowSize(width, height);
|
||||
nlassert(width == m_DevicePtr->HMDInfo.HResolution);
|
||||
nlassert(height == m_DevicePtr->HMDInfo.VResolution);
|
||||
|
||||
if (m_Driver->getPolygonMode() == UDriver::Filled)
|
||||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case 0:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
// stage 1:
|
||||
// (initBloom)
|
||||
// clear buffer
|
||||
// draw scene left
|
||||
return true;
|
||||
case 1:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
// stage 2:
|
||||
// draw scene right
|
||||
return true;
|
||||
case 2:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
// stage 3:
|
||||
// (endBloom)
|
||||
// draw interface 3d left
|
||||
return true;
|
||||
case 3:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
// stage 4:
|
||||
// draw interface 3d right
|
||||
return true;
|
||||
case 4:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
// stage 5:
|
||||
// (endInterfacesDisplayBloom)
|
||||
// draw interface 2d left
|
||||
return true;
|
||||
case 5:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
// stage 6:
|
||||
// draw interface 2d right
|
||||
return true;
|
||||
case 6:
|
||||
m_Stage = 0;
|
||||
m_SubStage = 0;
|
||||
// present
|
||||
m_OrientationCached = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case 0:
|
||||
++m_Stage;
|
||||
m_SubStage = 0;
|
||||
return true;
|
||||
case 1:
|
||||
m_Stage = 0;
|
||||
m_SubStage = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
nlerror("Invalid stage");
|
||||
m_Stage = 0;
|
||||
m_SubStage = 0;
|
||||
m_OrientationCached = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
const NL3D::CViewport &CStereoOVR::getCurrentViewport() const
|
||||
{
|
||||
if (m_Stage % 2) return m_LeftViewport;
|
||||
else return m_RightViewport;
|
||||
}
|
||||
|
||||
const NL3D::CFrustum &CStereoOVR::getCurrentFrustum(uint cid) const
|
||||
{
|
||||
if (m_Stage % 2) return m_LeftFrustum[cid];
|
||||
else return m_RightFrustum[cid];
|
||||
}
|
||||
|
||||
void CStereoOVR::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const
|
||||
{
|
||||
if (m_Stage % 2) camera->setFrustum(m_LeftFrustum[cid]);
|
||||
else camera->setFrustum(m_RightFrustum[cid]);
|
||||
}
|
||||
|
||||
void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const
|
||||
{
|
||||
CMatrix translate;
|
||||
if (m_Stage % 2) translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f));
|
||||
else translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f));
|
||||
CMatrix mat = m_CameraMatrix[cid] * translate;
|
||||
if (camera->getTransformMode() == NL3D::UTransformable::RotQuat)
|
||||
{
|
||||
camera->setPos(mat.getPos());
|
||||
camera->setRotQuat(mat.getRot());
|
||||
}
|
||||
else
|
||||
{
|
||||
// camera->setTransformMode(NL3D::UTransformable::DirectMatrix);
|
||||
camera->setMatrix(mat);
|
||||
}
|
||||
}
|
||||
|
||||
bool CStereoOVR::wantClear()
|
||||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case 1:
|
||||
m_SubStage = 1;
|
||||
return true;
|
||||
}
|
||||
return m_Driver->getPolygonMode() != UDriver::Filled;
|
||||
}
|
||||
|
||||
bool CStereoOVR::wantScene()
|
||||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
m_SubStage = 2;
|
||||
return true;
|
||||
}
|
||||
return m_Driver->getPolygonMode() != UDriver::Filled;
|
||||
}
|
||||
|
||||
bool CStereoOVR::wantInterface3D()
|
||||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case 3:
|
||||
case 4:
|
||||
m_SubStage = 3;
|
||||
return true;
|
||||
}
|
||||
return m_Driver->getPolygonMode() != UDriver::Filled;
|
||||
}
|
||||
|
||||
bool CStereoOVR::wantInterface2D()
|
||||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case 5:
|
||||
case 6:
|
||||
m_SubStage = 4;
|
||||
return true;
|
||||
}
|
||||
return m_Driver->getPolygonMode() != UDriver::Filled;
|
||||
}
|
||||
|
||||
|
||||
/// Returns non-NULL if a new render target was set
|
||||
bool CStereoOVR::beginRenderTarget()
|
||||
{
|
||||
// render target always set before driver clear
|
||||
// nlassert(m_SubStage <= 1);
|
||||
if (m_Driver && m_Stage == 1 && (m_Driver->getPolygonMode() == UDriver::Filled))
|
||||
{
|
||||
static_cast<CDriverUser *>(m_Driver)->setRenderTarget(*m_BarrelTexU, 0, 0, 0, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns true if a render target was fully drawn
|
||||
bool CStereoOVR::endRenderTarget()
|
||||
{
|
||||
// after rendering of course
|
||||
// nlassert(m_SubStage > 1);
|
||||
if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui
|
||||
{
|
||||
CTextureUser cu;
|
||||
(static_cast<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;
|
||||
m_Driver->getWindowSize(width, height);
|
||||
NL3D::IDriver *drvInternal = (static_cast<CDriverUser *>(m_Driver))->getDriver();
|
||||
NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr();
|
||||
barrelMat->setTexture(0, m_BarrelTex);
|
||||
|
||||
drvInternal->activePixelProgram(m_PixelProgram);
|
||||
|
||||
float w = float(m_BarrelQuadLeft.V1.x),// / float(width),
|
||||
h = float(m_BarrelQuadLeft.V2.y),// / float(height),
|
||||
x = float(m_BarrelQuadLeft.V0.x),/// / float(width),
|
||||
y = float(m_BarrelQuadLeft.V0.y);// / float(height);
|
||||
|
||||
float lensOffset = m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f;
|
||||
float lensShift = m_DevicePtr->HMDInfo.HScreenSize * 0.25f - lensOffset;
|
||||
float lensViewportShift = 4.0f * lensShift / m_DevicePtr->HMDInfo.HScreenSize;
|
||||
|
||||
float lensCenterX = x + (w + lensViewportShift * 0.5f) * 0.5f;
|
||||
float lensCenterY = y + h * 0.5f;
|
||||
float screenCenterX = x + w * 0.5f;
|
||||
float screenCenterY = y + h * 0.5f;
|
||||
float scaleX = (w / 2);
|
||||
float scaleY = (h / 2);
|
||||
float scaleInX = (2 / w);
|
||||
float scaleInY = (2 / h);
|
||||
|
||||
|
||||
drvInternal->setUniform2f(IDriver::PixelProgram,
|
||||
m_PixelProgram->ovrIndices().LensCenter,
|
||||
lensCenterX, lensCenterY);
|
||||
|
||||
drvInternal->setUniform2f(IDriver::PixelProgram,
|
||||
m_PixelProgram->ovrIndices().ScreenCenter,
|
||||
screenCenterX, screenCenterY);
|
||||
|
||||
drvInternal->setUniform2f(IDriver::PixelProgram,
|
||||
m_PixelProgram->ovrIndices().Scale,
|
||||
scaleX, scaleY);
|
||||
|
||||
drvInternal->setUniform2f(IDriver::PixelProgram,
|
||||
m_PixelProgram->ovrIndices().ScaleIn,
|
||||
scaleInX, scaleInY);
|
||||
|
||||
|
||||
drvInternal->setUniform4fv(IDriver::PixelProgram,
|
||||
m_PixelProgram->ovrIndices().HmdWarpParam,
|
||||
1, m_DevicePtr->HMDInfo.DistortionK);
|
||||
|
||||
m_Driver->drawQuad(m_BarrelQuadLeft, m_BarrelMat);
|
||||
|
||||
x = w;
|
||||
lensCenterX = x + (w - lensViewportShift * 0.5f) * 0.5f;
|
||||
screenCenterX = x + w * 0.5f;
|
||||
|
||||
|
||||
drvInternal->setUniform2f(IDriver::PixelProgram,
|
||||
m_PixelProgram->ovrIndices().LensCenter,
|
||||
lensCenterX, lensCenterY);
|
||||
|
||||
drvInternal->setUniform2f(IDriver::PixelProgram,
|
||||
m_PixelProgram->ovrIndices().ScreenCenter,
|
||||
screenCenterX, screenCenterY);
|
||||
|
||||
|
||||
m_Driver->drawQuad(m_BarrelQuadRight, m_BarrelMat);
|
||||
|
||||
drvInternal->activePixelProgram(NULL);
|
||||
m_Driver->enableFog(fogEnabled);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NLMISC::CQuat CStereoOVR::getOrientation() const
|
||||
{
|
||||
if (m_OrientationCached)
|
||||
return m_OrientationCache;
|
||||
|
||||
OVR::Quatf quatovr = m_DevicePtr->SensorFusion.GetPredictedOrientation();
|
||||
NLMISC::CMatrix coordsys;
|
||||
float csys[] = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, -1.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f,
|
||||
};
|
||||
coordsys.set(csys);
|
||||
NLMISC::CMatrix matovr;
|
||||
matovr.setRot(NLMISC::CQuat(quatovr.x, quatovr.y, quatovr.z, quatovr.w));
|
||||
NLMISC::CMatrix matr;
|
||||
matr.rotateX(NLMISC::Pi * 0.5f); // fix this properly... :) (note: removing this allows you to use rift while lying down)
|
||||
NLMISC::CMatrix matnel = matr * matovr * coordsys;
|
||||
NLMISC::CQuat finalquat = matnel.getRot();
|
||||
m_OrientationCache = finalquat;
|
||||
m_OrientationCached = true;
|
||||
return finalquat;
|
||||
}
|
||||
|
||||
/// Get GUI shift
|
||||
void CStereoOVR::getInterface2DShift(uint cid, float &x, float &y, float distance) const
|
||||
{
|
||||
#if 0
|
||||
|
||||
// todo: take into account m_EyePosition
|
||||
|
||||
NLMISC::CVector vector = CVector(0.f, -distance, 0.f);
|
||||
NLMISC::CQuat rot = getOrientation();
|
||||
rot.invert();
|
||||
NLMISC::CMatrix mat;
|
||||
mat.rotate(rot);
|
||||
//if (m_Stage % 2) mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f));
|
||||
//else mat.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f));
|
||||
mat.translate(vector);
|
||||
CVector proj = CStereoOVR::getCurrentFrustum(cid).project(mat.getPos());
|
||||
|
||||
NLMISC::CVector ipd;
|
||||
if (m_Stage % 2) ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f);
|
||||
else ipd = CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f);
|
||||
CVector projipd = CStereoOVR::getCurrentFrustum(cid).project(vector + ipd);
|
||||
CVector projvec = CStereoOVR::getCurrentFrustum(cid).project(vector);
|
||||
|
||||
x = (proj.x + projipd.x - projvec.x - 0.5f);
|
||||
y = (proj.y + projipd.y - projvec.y - 0.5f);
|
||||
|
||||
#elif 1
|
||||
|
||||
// Alternative method
|
||||
// todo: take into account m_EyePosition
|
||||
|
||||
NLMISC::CVector vec = CVector(0.f, -distance, 0.f);
|
||||
NLMISC::CVector ipd;
|
||||
if (m_Stage % 2) ipd = CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f);
|
||||
else ipd = CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f);
|
||||
|
||||
|
||||
NLMISC::CQuat rot = getOrientation();
|
||||
NLMISC::CQuat modrot = NLMISC::CQuat(CVector(0.f, 1.f, 0.f), NLMISC::Pi);
|
||||
rot = rot * modrot;
|
||||
float p = NLMISC::Pi + atan2f(2.0f * ((rot.x * rot.y) + (rot.z * rot.w)), 1.0f - 2.0f * ((rot.y * rot.y) + (rot.w * rot.w)));
|
||||
if (p > NLMISC::Pi) p -= NLMISC::Pi * 2.0f;
|
||||
float t = -atan2f(2.0f * ((rot.x * rot.w) + (rot.y * rot.z)), 1.0f - 2.0f * ((rot.z * rot.z) + (rot.w * rot.w)));// // asinf(2.0f * ((rot.x * rot.z) - (rot.w * rot.y)));
|
||||
|
||||
CVector rotshift = CVector(p, 0.f, t) * -distance;
|
||||
|
||||
CVector proj = CStereoOVR::getCurrentFrustum(cid).project(vec + ipd + rotshift);
|
||||
|
||||
x = (proj.x - 0.5f);
|
||||
y = (proj.y - 0.5f);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void CStereoOVR::setEyePosition(const NLMISC::CVector &v)
|
||||
{
|
||||
m_EyePosition = v;
|
||||
}
|
||||
|
||||
const NLMISC::CVector &CStereoOVR::getEyePosition() const
|
||||
{
|
||||
return m_EyePosition;
|
||||
}
|
||||
|
||||
void CStereoOVR::setScale(float s)
|
||||
{
|
||||
m_EyePosition = m_EyePosition * (s / m_Scale);
|
||||
m_Scale = s;
|
||||
}
|
||||
|
||||
void CStereoOVR::listDevices(std::vector<CStereoDeviceInfo> &devicesOut)
|
||||
{
|
||||
s_StereoOVRSystem.Init();
|
||||
OVR::DeviceEnumerator<OVR::HMDDevice> devices = s_DeviceManager->EnumerateDevices<OVR::HMDDevice>();
|
||||
uint id = 1;
|
||||
do
|
||||
{
|
||||
CStereoDeviceInfo deviceInfoOut;
|
||||
OVR::DeviceInfo deviceInfo;
|
||||
if (devices.IsAvailable())
|
||||
{
|
||||
devices.GetDeviceInfo(&deviceInfo);
|
||||
CStereoOVRDeviceHandle *handle = new CStereoOVRDeviceHandle();
|
||||
deviceInfoOut.Factory = static_cast<IStereoDeviceFactory *>(handle);
|
||||
handle->DeviceHandle = devices;
|
||||
deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; // 1; // OVR::HMDDevice
|
||||
deviceInfoOut.Library = CStereoDeviceInfo::OVR; // "Oculus SDK";
|
||||
deviceInfoOut.Manufacturer = deviceInfo.Manufacturer;
|
||||
deviceInfoOut.ProductName = deviceInfo.ProductName;
|
||||
stringstream ser;
|
||||
ser << id;
|
||||
deviceInfoOut.Serial = ser.str(); // can't get the real serial from the sdk...
|
||||
devicesOut.push_back(deviceInfoOut);
|
||||
++id;
|
||||
}
|
||||
|
||||
} while (devices.Next());
|
||||
}
|
||||
|
||||
bool CStereoOVR::isLibraryInUse()
|
||||
{
|
||||
nlassert(s_DeviceCounter >= 0);
|
||||
return s_DeviceCounter > 0;
|
||||
}
|
||||
|
||||
void CStereoOVR::releaseLibrary()
|
||||
{
|
||||
nlassert(s_DeviceCounter == 0);
|
||||
s_StereoOVRSystem.Release();
|
||||
}
|
||||
|
||||
bool CStereoOVR::isDeviceCreated()
|
||||
{
|
||||
return m_DevicePtr->HMDDevice != NULL;
|
||||
}
|
||||
|
||||
} /* namespace NL3D */
|
||||
|
||||
#endif /* HAVE_LIBOVR */
|
||||
|
||||
/* end of file */
|
249
code/nel/src/3d/stereo_ovr_fp.cpp
Normal file
249
code/nel/src/3d/stereo_ovr_fp.cpp
Normal file
|
@ -0,0 +1,249 @@
|
|||
/************************************************************************************
|
||||
|
||||
Filename : stereo_ovf_fp.cpp
|
||||
Content : Barrel fragment program compiled to a blob of assembly
|
||||
Created : July 01, 2013
|
||||
Modified by : Jan Boon (Kaetemi)
|
||||
|
||||
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
************************************************************************************/
|
||||
|
||||
namespace NL3D {
|
||||
const char *g_StereoOVR_fp40 =
|
||||
"!!ARBfp1.0\n"
|
||||
"OPTION NV_fragment_program2;\n"
|
||||
//# cgc version 3.1.0013, build date Apr 18 2012
|
||||
//# command line args: -profile fp40
|
||||
//# source file: pp_oculus_vr.cg
|
||||
//#vendor NVIDIA Corporation
|
||||
//#version 3.1.0.13
|
||||
//#profile fp40
|
||||
//#program pp_oculus_vr
|
||||
//#semantic pp_oculus_vr.cLensCenter
|
||||
//#semantic pp_oculus_vr.cScreenCenter
|
||||
//#semantic pp_oculus_vr.cScale
|
||||
//#semantic pp_oculus_vr.cScaleIn
|
||||
//#semantic pp_oculus_vr.cHmdWarpParam
|
||||
//#semantic pp_oculus_vr.cTex0 : TEX0
|
||||
//#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1
|
||||
//#var float2 cLensCenter : : c[0] : 1 : 1
|
||||
//#var float2 cScreenCenter : : c[1] : 2 : 1
|
||||
//#var float2 cScale : : c[2] : 3 : 1
|
||||
//#var float2 cScaleIn : : c[3] : 4 : 1
|
||||
//#var float4 cHmdWarpParam : : c[4] : 5 : 1
|
||||
//#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1
|
||||
//#var float4 oCol : $vout.COLOR : COL : 7 : 1
|
||||
//#const c[5] = 0.25 0.5 0
|
||||
"PARAM c[6] = { program.env[0..4],\n" // program.local->program.env!
|
||||
" { 0.25, 0.5, 0 } };\n"
|
||||
"TEMP R0;\n"
|
||||
"TEMP R1;\n"
|
||||
"SHORT TEMP H0;\n"
|
||||
"TEMP RC;\n"
|
||||
"TEMP HC;\n"
|
||||
"OUTPUT oCol = result.color;\n"
|
||||
"ADDR R0.xy, fragment.texcoord[0], -c[0];\n"
|
||||
"MULR R0.xy, R0, c[3];\n"
|
||||
"MULR R0.z, R0.y, R0.y;\n"
|
||||
"MADR R1.x, R0, R0, R0.z;\n"
|
||||
"MULR R0.zw, R1.x, c[4].xywz;\n"
|
||||
"MADR R1.y, R1.x, c[4], c[4].x;\n"
|
||||
"MADR R0.w, R0, R1.x, R1.y;\n"
|
||||
"MULR R0.z, R0, R1.x;\n"
|
||||
"MADR R0.z, R0, R1.x, R0.w;\n"
|
||||
"MULR R1.xy, R0, R0.z;\n"
|
||||
"MOVR R0.xy, c[5];\n"
|
||||
"ADDR R1.zw, R0.xyxy, c[1].xyxy;\n"
|
||||
"MOVR R0.zw, c[0].xyxy;\n"
|
||||
"MADR R0.zw, R1.xyxy, c[2].xyxy, R0;\n"
|
||||
"MINR R1.xy, R0.zwzw, R1.zwzw;\n"
|
||||
"ADDR R0.xy, -R0, c[1];\n"
|
||||
"MAXR R0.xy, R0, R1;\n"
|
||||
"SEQR H0.xy, R0, R0.zwzw;\n"
|
||||
"MULXC HC.x, H0, H0.y;\n"
|
||||
"IF EQ.x;\n"
|
||||
"MOVR oCol, c[5].z;\n"
|
||||
"ELSE;\n"
|
||||
"TEX oCol, R0.zwzw, texture[0], 2D;\n"
|
||||
"ENDIF;\n"
|
||||
"END\n";
|
||||
//# 24 instructions, 2 R-regs, 1 H-regs
|
||||
|
||||
const char *g_StereoOVR_arbfp1 =
|
||||
"!!ARBfp1.0\n"
|
||||
//# cgc version 3.1.0013, build date Apr 18 2012
|
||||
//# command line args: -profile arbfp1
|
||||
//# source file: pp_oculus_vr.cg
|
||||
//#vendor NVIDIA Corporation
|
||||
//#version 3.1.0.13
|
||||
//#profile arbfp1
|
||||
//#program pp_oculus_vr
|
||||
//#semantic pp_oculus_vr.cLensCenter
|
||||
//#semantic pp_oculus_vr.cScreenCenter
|
||||
//#semantic pp_oculus_vr.cScale
|
||||
//#semantic pp_oculus_vr.cScaleIn
|
||||
//#semantic pp_oculus_vr.cHmdWarpParam
|
||||
//#semantic pp_oculus_vr.cTex0 : TEX0
|
||||
//#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1
|
||||
//#var float2 cLensCenter : : c[0] : 1 : 1
|
||||
//#var float2 cScreenCenter : : c[1] : 2 : 1
|
||||
//#var float2 cScale : : c[2] : 3 : 1
|
||||
//#var float2 cScaleIn : : c[3] : 4 : 1
|
||||
//#var float4 cHmdWarpParam : : c[4] : 5 : 1
|
||||
//#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1
|
||||
//#var float4 oCol : $vout.COLOR : COL : 7 : 1
|
||||
//#const c[5] = 0.25 0.5 0 1
|
||||
"PARAM c[6] = { program.env[0..4],\n"
|
||||
" { 0.25, 0.5, 0, 1 } };\n"
|
||||
"TEMP R0;\n"
|
||||
"TEMP R1;\n"
|
||||
"ADD R0.xy, fragment.texcoord[0], -c[0];\n"
|
||||
"MUL R0.xy, R0, c[3];\n"
|
||||
"MUL R0.z, R0.y, R0.y;\n"
|
||||
"MAD R0.z, R0.x, R0.x, R0;\n"
|
||||
"MUL R0.w, R0.z, c[4];\n"
|
||||
"MUL R0.w, R0, R0.z;\n"
|
||||
"MAD R1.y, R0.z, c[4], c[4].x;\n"
|
||||
"MUL R1.x, R0.z, c[4].z;\n"
|
||||
"MAD R1.x, R0.z, R1, R1.y;\n"
|
||||
"MAD R0.z, R0.w, R0, R1.x;\n"
|
||||
"MUL R0.xy, R0, R0.z;\n"
|
||||
"MOV R0.zw, c[5].xyxy;\n"
|
||||
"ADD R1.xy, R0.zwzw, c[1];\n"
|
||||
"MUL R0.xy, R0, c[2];\n"
|
||||
"ADD R0.xy, R0, c[0];\n"
|
||||
"MIN R1.xy, R1, R0;\n"
|
||||
"ADD R0.zw, -R0, c[1].xyxy;\n"
|
||||
"MAX R0.zw, R0, R1.xyxy;\n"
|
||||
"ADD R0.zw, R0, -R0.xyxy;\n"
|
||||
"ABS R0.zw, R0;\n"
|
||||
"CMP R0.zw, -R0, c[5].z, c[5].w;\n"
|
||||
"MUL R0.z, R0, R0.w;\n"
|
||||
"ABS R0.z, R0;\n"
|
||||
"CMP R0.z, -R0, c[5], c[5].w;\n"
|
||||
"ABS R1.x, R0.z;\n"
|
||||
"TEX R0, R0, texture[0], 2D;\n"
|
||||
"CMP R1.x, -R1, c[5].z, c[5].w;\n"
|
||||
"CMP result.color, -R1.x, R0, c[5].z;\n"
|
||||
"END\n";
|
||||
//# 28 instructions, 2 R-regs
|
||||
|
||||
const char *g_StereoOVR_ps_2_0 =
|
||||
"ps_2_0\n"
|
||||
// cgc version 3.1.0013, build date Apr 18 2012
|
||||
// command line args: -profile ps_2_0
|
||||
// source file: pp_oculus_vr.cg
|
||||
//vendor NVIDIA Corporation
|
||||
//version 3.1.0.13
|
||||
//profile ps_2_0
|
||||
//program pp_oculus_vr
|
||||
//semantic pp_oculus_vr.cLensCenter
|
||||
//semantic pp_oculus_vr.cScreenCenter
|
||||
//semantic pp_oculus_vr.cScale
|
||||
//semantic pp_oculus_vr.cScaleIn
|
||||
//semantic pp_oculus_vr.cHmdWarpParam
|
||||
//semantic pp_oculus_vr.cTex0 : TEX0
|
||||
//var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1
|
||||
//var float2 cLensCenter : : c[0] : 1 : 1
|
||||
//var float2 cScreenCenter : : c[1] : 2 : 1
|
||||
//var float2 cScale : : c[2] : 3 : 1
|
||||
//var float2 cScaleIn : : c[3] : 4 : 1
|
||||
//var float4 cHmdWarpParam : : c[4] : 5 : 1
|
||||
//var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1
|
||||
//var float4 oCol : $vout.COLOR : COL : 7 : 1
|
||||
//const c[5] = -0.25 -0.5 0.25 0.5
|
||||
//const c[6] = 1 0
|
||||
"dcl_2d s0\n"
|
||||
"def c5, -0.25000000, -0.50000000, 0.25000000, 0.50000000\n"
|
||||
"def c6, 1.00000000, 0.00000000, 0, 0\n"
|
||||
"dcl t0.xy\n"
|
||||
"add r0.xy, t0, -c0\n"
|
||||
"mul r4.xy, r0, c3\n"
|
||||
"mul r0.x, r4.y, r4.y\n"
|
||||
"mad r0.x, r4, r4, r0\n"
|
||||
"mul r1.x, r0, c4.w\n"
|
||||
"mul r1.x, r1, r0\n"
|
||||
"mad r3.x, r0, c4.y, c4\n"
|
||||
"mul r2.x, r0, c4.z\n"
|
||||
"mad r2.x, r0, r2, r3\n"
|
||||
"mad r0.x, r1, r0, r2\n"
|
||||
"mul r0.xy, r4, r0.x\n"
|
||||
"mul r0.xy, r0, c2\n"
|
||||
"add r3.xy, r0, c0\n"
|
||||
"mov r1.x, c5.z\n"
|
||||
"mov r1.y, c5.w\n"
|
||||
"mov r2.xy, c1\n"
|
||||
"add r2.xy, r1, r2\n"
|
||||
"mov r1.xy, c1\n"
|
||||
"min r2.xy, r2, r3\n"
|
||||
"add r1.xy, c5, r1\n"
|
||||
"max r1.xy, r1, r2\n"
|
||||
"add r1.xy, r1, -r3\n"
|
||||
"abs r1.xy, r1\n"
|
||||
"cmp r1.xy, -r1, c6.x, c6.y\n"
|
||||
"mul_pp r1.x, r1, r1.y\n"
|
||||
"abs_pp r1.x, r1\n"
|
||||
"cmp_pp r1.x, -r1, c6, c6.y\n"
|
||||
"abs_pp r1.x, r1\n"
|
||||
"texld r0, r3, s0\n"
|
||||
"cmp r0, -r1.x, r0, c6.y\n"
|
||||
"mov oC0, r0\n";
|
||||
|
||||
const char *g_StereoOVR_glsl330f =
|
||||
"#version 330\n"
|
||||
"\n"
|
||||
"bool _TMP2;\n"
|
||||
"bvec2 _TMP1;\n"
|
||||
"vec2 _TMP3;\n"
|
||||
"uniform vec2 cLensCenter;\n"
|
||||
"uniform vec2 cScreenCenter;\n"
|
||||
"uniform vec2 cScale;\n"
|
||||
"uniform vec2 cScaleIn;\n"
|
||||
"uniform vec4 cHmdWarpParam;\n"
|
||||
"uniform sampler2D nlTex0;\n"
|
||||
"vec2 _TMP10;\n"
|
||||
"vec2 _b0011;\n"
|
||||
"vec2 _a0011;\n"
|
||||
"in vec4 nlTexCoord0;\n"
|
||||
"out vec4 nlCol;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec2 _theta;\n"
|
||||
" float _rSq;\n"
|
||||
" vec2 _theta1;\n"
|
||||
" vec2 _tc;\n"
|
||||
"\n"
|
||||
" _theta = (nlTexCoord0.xy - cLensCenter)*cScaleIn;\n"
|
||||
" _rSq = _theta.x*_theta.x + _theta.y*_theta.y;\n"
|
||||
" _theta1 = _theta*(cHmdWarpParam.x + cHmdWarpParam.y*_rSq + cHmdWarpParam.z*_rSq*_rSq + cHmdWarpParam.w*_rSq*_rSq*_rSq);\n"
|
||||
" _tc = cLensCenter + cScale*_theta1;\n"
|
||||
" _a0011 = cScreenCenter - vec2( 0.25, 0.5);\n"
|
||||
" _b0011 = cScreenCenter + vec2( 0.25, 0.5);\n"
|
||||
" _TMP3 = min(_b0011, _tc);\n"
|
||||
" _TMP10 = max(_a0011, _TMP3);\n"
|
||||
" _TMP1 = bvec2(_TMP10.x == _tc.x, _TMP10.y == _tc.y);\n"
|
||||
" _TMP2 = _TMP1.x && _TMP1.y;\n"
|
||||
" if (!_TMP2) {\n"
|
||||
" nlCol = vec4(0, 0, 0, 0);\n"
|
||||
" } else {\n"
|
||||
" nlCol = texture(nlTex0, _tc);\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
}
|
||||
|
||||
/* end of file */
|
|
@ -560,49 +560,159 @@ const char* NL3D_SimpleStartVegetableProgram=
|
|||
MOV o[COL0].xyz, v[3]; # col.RGBA= vertex color \n\
|
||||
";
|
||||
|
||||
class CVertexProgramVeget : public CVertexProgram
|
||||
{
|
||||
public:
|
||||
struct CIdx
|
||||
{
|
||||
// 0-3 modelViewProjection
|
||||
// 4
|
||||
// 5
|
||||
// 6 fog
|
||||
// 7
|
||||
uint ProgramConstants0; // 8
|
||||
uint DirectionalLight; // 9
|
||||
uint ViewCenter; // 10
|
||||
uint NegInvTransDist; // 11
|
||||
// 12
|
||||
// 13
|
||||
// 14
|
||||
// 15
|
||||
uint AngleAxis; // 16
|
||||
uint Wind; // 17
|
||||
uint CosCoeff0; // 18
|
||||
uint CosCoeff1; // 19
|
||||
uint CosCoeff2; // 20
|
||||
uint QuatConstants; // 21
|
||||
uint PiConstants; // 22
|
||||
uint LUTSize; // 23 (value = 64)
|
||||
uint LUT[NL3D_VEGETABLE_VP_LUT_SIZE]; // 32+
|
||||
};
|
||||
CVertexProgramVeget(uint vpType, bool fogEnabled)
|
||||
{
|
||||
// nelvp
|
||||
{
|
||||
CSource *source = new CSource();
|
||||
source->Profile = nelvp;
|
||||
source->DisplayName = "nelvp/Veget";
|
||||
|
||||
// Init the Vertex Program.
|
||||
string vpgram;
|
||||
// start always with Bend.
|
||||
if( vpType==NL3D_VEGETABLE_RDRPASS_LIGHTED || vpType==NL3D_VEGETABLE_RDRPASS_LIGHTED_2SIDED )
|
||||
{
|
||||
source->DisplayName += "/Bend";
|
||||
vpgram= NL3D_BendProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
source->DisplayName += "/FastBend";
|
||||
vpgram= NL3D_FastBendProgram;
|
||||
}
|
||||
|
||||
// combine the VP according to Type
|
||||
switch(vpType)
|
||||
{
|
||||
case NL3D_VEGETABLE_RDRPASS_LIGHTED:
|
||||
case NL3D_VEGETABLE_RDRPASS_LIGHTED_2SIDED:
|
||||
source->DisplayName += "/Lighted";
|
||||
vpgram+= string(NL3D_LightedStartVegetableProgram);
|
||||
break;
|
||||
case NL3D_VEGETABLE_RDRPASS_UNLIT:
|
||||
case NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED:
|
||||
source->DisplayName += "/Unlit";
|
||||
vpgram+= string(NL3D_UnlitVegetableProgram);
|
||||
break;
|
||||
case NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED_ZSORT:
|
||||
source->DisplayName += "/UnlitAlphaBlend";
|
||||
vpgram+= string(NL3D_UnlitAlphaBlendVegetableProgram);
|
||||
break;
|
||||
}
|
||||
|
||||
// common end of VP
|
||||
vpgram+= string(NL3D_CommonEndVegetableProgram);
|
||||
|
||||
if (fogEnabled)
|
||||
{
|
||||
source->DisplayName += "/Fog";
|
||||
vpgram+= string(NL3D_VegetableProgramFog);
|
||||
}
|
||||
|
||||
vpgram+="\nEND\n";
|
||||
|
||||
source->setSource(vpgram);
|
||||
|
||||
source->ParamIndices["modelViewProjection"] = 0;
|
||||
source->ParamIndices["fog"] = 6;
|
||||
source->ParamIndices["programConstants0"] = 8;
|
||||
source->ParamIndices["directionalLight"] = 9;
|
||||
source->ParamIndices["viewCenter"] = 10;
|
||||
source->ParamIndices["negInvTransDist"] = 11;
|
||||
source->ParamIndices["angleAxis"] = 16;
|
||||
source->ParamIndices["wind"] = 17;
|
||||
source->ParamIndices["cosCoeff0"] = 18;
|
||||
source->ParamIndices["cosCoeff1"] = 19;
|
||||
source->ParamIndices["cosCoeff2"] = 20;
|
||||
source->ParamIndices["quatConstants"] = 21;
|
||||
source->ParamIndices["piConstants"] = 22;
|
||||
source->ParamIndices["lutSize"] = 23;
|
||||
for (uint i = 0; i < NL3D_VEGETABLE_VP_LUT_SIZE; ++i)
|
||||
{
|
||||
source->ParamIndices[NLMISC::toString("lut[%i]", i)] = 32 + i;
|
||||
}
|
||||
|
||||
addSource(source);
|
||||
}
|
||||
// TODO_VP_GLSL
|
||||
}
|
||||
virtual ~CVertexProgramVeget()
|
||||
{
|
||||
|
||||
}
|
||||
virtual void buildInfo()
|
||||
{
|
||||
m_Idx.ProgramConstants0 = getUniformIndex("programConstants0");
|
||||
nlassert(m_Idx.ProgramConstants0 != ~0);
|
||||
m_Idx.DirectionalLight = getUniformIndex("directionalLight");
|
||||
nlassert(m_Idx.DirectionalLight != ~0);
|
||||
m_Idx.ViewCenter = getUniformIndex("viewCenter");
|
||||
nlassert(m_Idx.ViewCenter != ~0);
|
||||
m_Idx.NegInvTransDist = getUniformIndex("negInvTransDist");
|
||||
nlassert(m_Idx.NegInvTransDist != ~0);
|
||||
m_Idx.AngleAxis = getUniformIndex("angleAxis");
|
||||
nlassert(m_Idx.AngleAxis != ~0);
|
||||
m_Idx.Wind = getUniformIndex("wind");
|
||||
nlassert(m_Idx.Wind != ~0);
|
||||
m_Idx.CosCoeff0 = getUniformIndex("cosCoeff0");
|
||||
nlassert(m_Idx.CosCoeff0 != ~0);
|
||||
m_Idx.CosCoeff1 = getUniformIndex("cosCoeff1");
|
||||
nlassert(m_Idx.CosCoeff1 != ~0);
|
||||
m_Idx.CosCoeff2 = getUniformIndex("cosCoeff2");
|
||||
nlassert(m_Idx.CosCoeff2 != ~0);
|
||||
m_Idx.QuatConstants = getUniformIndex("quatConstants");
|
||||
nlassert(m_Idx.QuatConstants != ~0);
|
||||
m_Idx.PiConstants = getUniformIndex("piConstants");
|
||||
nlassert(m_Idx.PiConstants != ~0);
|
||||
m_Idx.LUTSize = getUniformIndex("lutSize");
|
||||
nlassert(m_Idx.LUTSize != ~0);
|
||||
for (uint i = 0; i < NL3D_VEGETABLE_VP_LUT_SIZE; ++i)
|
||||
{
|
||||
m_Idx.LUT[i] = getUniformIndex(NLMISC::toString("lut[%i]", i));
|
||||
nlassert(m_Idx.LUT[i] != ~0);
|
||||
}
|
||||
}
|
||||
const CIdx &idx() const { return m_Idx; }
|
||||
private:
|
||||
CIdx m_Idx;
|
||||
};
|
||||
|
||||
// ***************************************************************************
|
||||
void CVegetableManager::initVertexProgram(uint vpType, bool fogEnabled)
|
||||
{
|
||||
nlassert(_LastDriver); // update driver should have been called at least once !
|
||||
// Init the Vertex Program.
|
||||
string vpgram;
|
||||
// start always with Bend.
|
||||
if( vpType==NL3D_VEGETABLE_RDRPASS_LIGHTED || vpType==NL3D_VEGETABLE_RDRPASS_LIGHTED_2SIDED )
|
||||
vpgram= NL3D_BendProgram;
|
||||
else
|
||||
vpgram= NL3D_FastBendProgram;
|
||||
|
||||
// combine the VP according to Type
|
||||
switch(vpType)
|
||||
{
|
||||
case NL3D_VEGETABLE_RDRPASS_LIGHTED:
|
||||
case NL3D_VEGETABLE_RDRPASS_LIGHTED_2SIDED:
|
||||
vpgram+= string(NL3D_LightedStartVegetableProgram);
|
||||
break;
|
||||
case NL3D_VEGETABLE_RDRPASS_UNLIT:
|
||||
case NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED:
|
||||
vpgram+= string(NL3D_UnlitVegetableProgram);
|
||||
break;
|
||||
case NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED_ZSORT:
|
||||
vpgram+= string(NL3D_UnlitAlphaBlendVegetableProgram);
|
||||
break;
|
||||
}
|
||||
|
||||
// common end of VP
|
||||
vpgram+= string(NL3D_CommonEndVegetableProgram);
|
||||
|
||||
if (fogEnabled)
|
||||
{
|
||||
vpgram+= string(NL3D_VegetableProgramFog);
|
||||
}
|
||||
|
||||
vpgram+="\nEND\n";
|
||||
|
||||
|
||||
// create VP.
|
||||
_VertexProgram[vpType][fogEnabled ? 1 : 0] = new CVertexProgram(vpgram.c_str());
|
||||
|
||||
_VertexProgram[vpType][fogEnabled ? 1 : 0] = new CVertexProgramVeget(vpType, fogEnabled);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1756,42 +1866,48 @@ public:
|
|||
|
||||
|
||||
// ***************************************************************************
|
||||
void CVegetableManager::setupVertexProgramConstants(IDriver *driver)
|
||||
void CVegetableManager::setupVertexProgramConstants(IDriver *driver, bool fogEnabled)
|
||||
{
|
||||
nlassert(_ActiveVertexProgram);
|
||||
|
||||
|
||||
// Standard
|
||||
// setup VertexProgram constants.
|
||||
// c[0..3] take the ModelViewProjection Matrix. After setupModelMatrix();
|
||||
driver->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity);
|
||||
driver->setUniformMatrix(IDriver::VertexProgram, _ActiveVertexProgram->getUniformIndex(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity);
|
||||
// c[6] take the Fog vector. After setupModelMatrix();
|
||||
driver->setConstantFog(6);
|
||||
if (fogEnabled)
|
||||
{
|
||||
driver->setUniformFog(IDriver::VertexProgram, _ActiveVertexProgram->getUniformIndex(CGPUProgramIndex::Fog));
|
||||
}
|
||||
// c[8] take useful constants.
|
||||
driver->setConstant(8, 0, 1, 0.5f, 2);
|
||||
driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().ProgramConstants0, 0, 1, 0.5f, 2);
|
||||
// c[9] take normalized directional light
|
||||
driver->setConstant(9, _DirectionalLight);
|
||||
driver->setUniform3f(IDriver::VertexProgram, _ActiveVertexProgram->idx().DirectionalLight, _DirectionalLight);
|
||||
// c[10] take pos of camera
|
||||
driver->setConstant(10, _ViewCenter);
|
||||
driver->setUniform3f(IDriver::VertexProgram, _ActiveVertexProgram->idx().ViewCenter, _ViewCenter);
|
||||
// c[11] take factor for Blend formula
|
||||
driver->setConstant(11, -1.f/NL3D_VEGETABLE_BLOCK_BLEND_TRANSITION_DIST, 0, 0, 0);
|
||||
driver->setUniform1f(IDriver::VertexProgram, _ActiveVertexProgram->idx().NegInvTransDist, -1.f/NL3D_VEGETABLE_BLOCK_BLEND_TRANSITION_DIST);
|
||||
|
||||
|
||||
|
||||
// Bend.
|
||||
// c[16]= quaternion axis. w==1, and z must be 0
|
||||
driver->setConstant( 16, _AngleAxis.x, _AngleAxis.y, _AngleAxis.z, 1);
|
||||
driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().AngleAxis, _AngleAxis, 1);
|
||||
// c[17]= {timeAnim, WindPower, WindPower*(1-WindBendMin)/2, 0)}
|
||||
driver->setConstant( 17, (float)_WindAnimTime, _WindPower, _WindPower*(1-_WindBendMin)/2, 0 );
|
||||
driver->setUniform3f(IDriver::VertexProgram, _ActiveVertexProgram->idx().Wind, (float)_WindAnimTime, _WindPower, _WindPower * (1 - _WindBendMin) / 2);
|
||||
// c[18]= High order Taylor cos coefficient: { -1/2, 1/24, -1/720, 1/40320 }
|
||||
driver->setConstant( 18, -1/2.f, 1/24.f, -1/720.f, 1/40320.f );
|
||||
driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().CosCoeff0, -1/2.f, 1/24.f, -1/720.f, 1/40320.f );
|
||||
// c[19]= Low order Taylor cos coefficient: { 1, -1/2, 1/24, -1/720 }
|
||||
driver->setConstant( 19, 1, -1/2.f, 1/24.f, -1/720.f );
|
||||
driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().CosCoeff1, 1, -1/2.f, 1/24.f, -1/720.f );
|
||||
// c[20]= Low order Taylor sin coefficient: { 1, -1/6, 1/120, -1/5040 }
|
||||
driver->setConstant( 20, 1, -1/6.f, 1/120.f, -1/5040.f );
|
||||
driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().CosCoeff2, 1, -1/6.f, 1/120.f, -1/5040.f );
|
||||
// c[21]= Special constant vector for quatToMatrix: { 0, 1, -1, 0 }
|
||||
driver->setConstant( 21, 0.f, 1.f, -1.f, 0.f);
|
||||
driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().QuatConstants, 0.f, 1.f, -1.f, 0.f);
|
||||
// c[22]= {0.5f, Pi, 2*Pi, 1/(2*Pi)}
|
||||
driver->setConstant( 22, 0.5f, (float)Pi, (float)(2*Pi), (float)(1/(2*Pi)) );
|
||||
driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().PiConstants, 0.5f, (float)Pi, (float)(2*Pi), (float)(1/(2*Pi)));
|
||||
// c[23]= {NL3D_VEGETABLE_VP_LUT_SIZE, 0, 0, 0}. NL3D_VEGETABLE_VP_LUT_SIZE==64.
|
||||
driver->setConstant( 23, NL3D_VEGETABLE_VP_LUT_SIZE, 0.f, 0.f, 0.f );
|
||||
driver->setUniform1f(IDriver::VertexProgram, _ActiveVertexProgram->idx().LUTSize, NL3D_VEGETABLE_VP_LUT_SIZE);
|
||||
|
||||
|
||||
// Fill constant. Start at 32.
|
||||
|
@ -1799,7 +1915,7 @@ void CVegetableManager::setupVertexProgramConstants(IDriver *driver)
|
|||
{
|
||||
CVector2f cur= _WindTable[i];
|
||||
CVector2f delta= _WindDeltaTable[i];
|
||||
driver->setConstant( 32+i, cur.x, cur.y, delta.x, delta.y );
|
||||
driver->setUniform4f(IDriver::VertexProgram, _ActiveVertexProgram->idx().LUT[i], cur.x, cur.y, delta.x, delta.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1925,10 +2041,6 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front
|
|||
}
|
||||
|
||||
|
||||
// setup VP constants.
|
||||
setupVertexProgramConstants(driver);
|
||||
|
||||
|
||||
// Setup TexEnvs for Dynamic lightmapping
|
||||
//--------------------
|
||||
// if the dynamic lightmap is provided
|
||||
|
@ -1968,6 +2080,12 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front
|
|||
_VegetableMaterial.setZWrite(true);
|
||||
_VegetableMaterial.setAlphaTestThreshold(0.5f);
|
||||
|
||||
bool uprogst = driver->isUniformProgramState();
|
||||
bool progstateset[NL3D_VEGETABLE_NRDRPASS];
|
||||
for (sint rdrPass = 0; rdrPass < NL3D_VEGETABLE_NRDRPASS; ++rdrPass)
|
||||
{
|
||||
progstateset[rdrPass] = false;
|
||||
}
|
||||
|
||||
/*
|
||||
Prefer sort with Soft / Hard first.
|
||||
|
@ -1995,14 +2113,20 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front
|
|||
// set the 2Sided flag in the material
|
||||
_VegetableMaterial.setDoubleSided( doubleSided );
|
||||
|
||||
|
||||
// Activate the unique material.
|
||||
driver->setupMaterial(_VegetableMaterial);
|
||||
|
||||
// activate Vertex program first.
|
||||
//nlinfo("\nSTARTVP\n%s\nENDVP\n", _VertexProgram[rdrPass]->getProgram().c_str());
|
||||
|
||||
nlverify(driver->activeVertexProgram(_VertexProgram[rdrPass][fogged ? 1 : 0]));
|
||||
_ActiveVertexProgram = _VertexProgram[rdrPass][fogged ? 1 : 0];
|
||||
nlverify(driver->activeVertexProgram(_ActiveVertexProgram));
|
||||
|
||||
// Set VP constants
|
||||
if (!progstateset[uprogst ? rdrPass : 0])
|
||||
{
|
||||
setupVertexProgramConstants(driver, uprogst ? fogged : true);
|
||||
}
|
||||
|
||||
// Activate the unique material.
|
||||
driver->setupMaterial(_VegetableMaterial);
|
||||
|
||||
// Activate the good VBuffer
|
||||
vbAllocator.activate();
|
||||
|
@ -2222,6 +2346,7 @@ void CVegetableManager::render(const CVector &viewCenter, const CVector &front
|
|||
|
||||
// disable VertexProgram.
|
||||
driver->activeVertexProgram(NULL);
|
||||
_ActiveVertexProgram = NULL;
|
||||
|
||||
|
||||
// restore Fog.
|
||||
|
@ -2261,25 +2386,25 @@ void CVegetableManager::setupRenderStateForBlendLayerModel(IDriver *driver)
|
|||
// set model matrix to the manager matrix.
|
||||
driver->setupModelMatrix(_ManagerMatrix);
|
||||
|
||||
// setup VP constants.
|
||||
setupVertexProgramConstants(driver);
|
||||
|
||||
// Setup RdrPass.
|
||||
//=============
|
||||
uint rdrPass= NL3D_VEGETABLE_RDRPASS_UNLIT_2SIDED_ZSORT;
|
||||
|
||||
// Activate the unique material (correclty setuped for AlphaBlend in render()).
|
||||
driver->setupMaterial(_VegetableMaterial);
|
||||
|
||||
// activate Vertex program first.
|
||||
//nlinfo("\nSTARTVP\n%s\nENDVP\n", _VertexProgram[rdrPass]->getProgram().c_str());
|
||||
nlverify(driver->activeVertexProgram(_VertexProgram[rdrPass][fogged ? 1 : 0]));
|
||||
_ActiveVertexProgram = _VertexProgram[rdrPass][fogged ? 1 : 0];
|
||||
nlverify(driver->activeVertexProgram(_ActiveVertexProgram));
|
||||
|
||||
if (fogged)
|
||||
// setup VP constants.
|
||||
setupVertexProgramConstants(driver, fogged);
|
||||
|
||||
/*if (fogged) // duplicate
|
||||
{
|
||||
driver->setConstantFog(6);
|
||||
}
|
||||
driver->setCon/stantFog(6);
|
||||
}*/
|
||||
|
||||
// Activate the unique material (correclty setuped for AlphaBlend in render()).
|
||||
driver->setupMaterial(_VegetableMaterial);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2302,6 +2427,7 @@ void CVegetableManager::exitRenderStateForBlendLayerModel(IDriver *driver)
|
|||
{
|
||||
// disable VertexProgram.
|
||||
driver->activeVertexProgram(NULL);
|
||||
_ActiveVertexProgram = NULL;
|
||||
|
||||
// restore Fog.
|
||||
driver->enableFog(_BkupFog);
|
||||
|
|
|
@ -98,7 +98,7 @@ void CVegetableVBAllocator::updateDriver(IDriver *driver)
|
|||
_VBHardOk= false;
|
||||
|
||||
// Driver must support VP.
|
||||
nlassert(_Driver->isVertexProgramSupported());
|
||||
nlassert(_Driver->supportVertexProgram());
|
||||
|
||||
// must reallocate the VertexBuffer.
|
||||
if( _NumVerticesAllocated>0 )
|
||||
|
|
|
@ -24,34 +24,28 @@
|
|||
namespace NL3D
|
||||
{
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
IVertexProgramDrvInfos::IVertexProgramDrvInfos (IDriver *drv, ItVtxPrgDrvInfoPtrList it)
|
||||
|
||||
CVertexProgram::CVertexProgram()
|
||||
{
|
||||
_Driver= drv;
|
||||
_DriverIterator= it;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
IVertexProgramDrvInfos::~IVertexProgramDrvInfos ()
|
||||
|
||||
CVertexProgram::CVertexProgram(const char *nelvp)
|
||||
{
|
||||
_Driver->removeVtxPrgDrvInfoPtr (_DriverIterator);
|
||||
CSource *source = new CSource();
|
||||
source->Profile = IGPUProgram::nelvp;
|
||||
source->setSource(nelvp);
|
||||
addSource(source);
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
CVertexProgram::CVertexProgram (const char* program)
|
||||
{
|
||||
_Program=program;
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
CVertexProgram::~CVertexProgram ()
|
||||
{
|
||||
// Must kill the drv mirror of this VB.
|
||||
_DrvInfo.kill();
|
||||
|
||||
}
|
||||
|
||||
} // NL3D
|
||||
|
|
|
@ -227,8 +227,7 @@ void CWaterEnvMap::doInit()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static CVertexProgram testMeshVP(
|
||||
static const char *testMeshVPstr =
|
||||
"!!VP1.0\n\
|
||||
DP4 o[HPOS].x, c[0], v[0]; \n\
|
||||
DP4 o[HPOS].y, c[1], v[0]; \n\
|
||||
|
@ -236,14 +235,57 @@ static CVertexProgram testMeshVP(
|
|||
DP4 o[HPOS].w, c[3], v[0]; \n\
|
||||
MAD o[COL0], v[8], c[4].xxxx, c[4].yyyy; \n\
|
||||
MOV o[TEX0], v[8]; \n\
|
||||
END"
|
||||
);
|
||||
END";
|
||||
|
||||
|
||||
class CVertexProgramTestMeshVP : public CVertexProgram
|
||||
{
|
||||
public:
|
||||
struct CIdx
|
||||
{
|
||||
uint ProgramConstant0;
|
||||
};
|
||||
CVertexProgramTestMeshVP()
|
||||
{
|
||||
// nelvp
|
||||
{
|
||||
CSource *source = new CSource();
|
||||
source->Profile = nelvp;
|
||||
source->DisplayName = "testMeshVP/nelvp";
|
||||
source->setSourcePtr(testMeshVPstr);
|
||||
source->ParamIndices["modelViewProjection"] = 0;
|
||||
source->ParamIndices["programConstant0"] = 4;
|
||||
addSource(source);
|
||||
}
|
||||
// TODO_VP_GLSL
|
||||
}
|
||||
virtual ~CVertexProgramTestMeshVP()
|
||||
{
|
||||
|
||||
}
|
||||
virtual void buildInfo()
|
||||
{
|
||||
m_Idx.ProgramConstant0 = getUniformIndex("programConstant0");
|
||||
nlassert(m_Idx.ProgramConstant0 != ~0);
|
||||
}
|
||||
inline const CIdx &idx() { return m_Idx; }
|
||||
private:
|
||||
CIdx m_Idx;
|
||||
};
|
||||
|
||||
|
||||
static NLMISC::CSmartPtr<CVertexProgramTestMeshVP> testMeshVP;
|
||||
|
||||
|
||||
|
||||
// *******************************************************************************
|
||||
void CWaterEnvMap::renderTestMesh(IDriver &driver)
|
||||
{
|
||||
if (!testMeshVP)
|
||||
{
|
||||
testMeshVP = new CVertexProgramTestMeshVP();
|
||||
}
|
||||
|
||||
doInit();
|
||||
CMaterial testMat;
|
||||
testMat.setLighting(false);
|
||||
|
@ -257,13 +299,12 @@ void CWaterEnvMap::renderTestMesh(IDriver &driver)
|
|||
testMat.setZWrite(false);
|
||||
testMat.setZFunc(CMaterial::always);
|
||||
// tmp : test cubemap
|
||||
driver.activeVertexProgram(&testMeshVP);
|
||||
driver.activeVertexProgram(testMeshVP);
|
||||
driver.activeVertexBuffer(_TestVB);
|
||||
driver.activeIndexBuffer(_TestIB);
|
||||
driver.setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity); // tmp
|
||||
_MaterialPassThruZTest.setTexture(0, _EnvCubic);
|
||||
driver.setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity);
|
||||
driver.setConstant(4, 2.f, 1.f, 0.f, 0.f);
|
||||
driver.setUniformMatrix(IDriver::VertexProgram, testMeshVP->getUniformIndex(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity);
|
||||
driver.setUniform2f(IDriver::VertexProgram, testMeshVP->idx().ProgramConstant0, 2.f, 1.f);
|
||||
//driver.renderTriangles(testMat, 0, TEST_VB_NUM_TRIS);
|
||||
driver.renderTriangles(_MaterialPassThruZTest, 0, TEST_VB_NUM_TRIS);
|
||||
driver.activeVertexProgram(NULL);
|
||||
|
|
|
@ -61,7 +61,7 @@ void CWaterModel::setupVertexBuffer(CVertexBuffer &vb, uint numWantedVertices, I
|
|||
vb.setNumVertices(0);
|
||||
vb.setName("Water");
|
||||
vb.setPreferredMemory(CVertexBuffer::AGPPreferred, false);
|
||||
if (drv->isWaterShaderSupported())
|
||||
if (drv->supportWaterShader())
|
||||
{
|
||||
vb.setVertexFormat(CVertexBuffer::PositionFlag);
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ void CWaterModel::traverseRender()
|
|||
|
||||
|
||||
#ifndef FORCE_SIMPLE_WATER_RENDER
|
||||
if (!drv->isWaterShaderSupported())
|
||||
if (!drv->supportWaterShader())
|
||||
#endif
|
||||
{
|
||||
doSimpleRender(drv);
|
||||
|
@ -903,11 +903,12 @@ void CWaterModel::setupMaterialNVertexShader(IDriver *drv, CWaterShape *shape, c
|
|||
_WaterMat.setZWrite(true);
|
||||
_WaterMat.setShader(CMaterial::Water);
|
||||
}
|
||||
const uint cstOffset = 5; // 4 places for the matrix
|
||||
NLMISC::CVectorH cst[13];
|
||||
//=========================//
|
||||
// setup Water material //
|
||||
//=========================//
|
||||
shape->initVertexProgram();
|
||||
CVertexProgramWaterVPNoWave *program = shape->_ColorMap ? CWaterShape::_VertexProgramNoWaveDiffuse : CWaterShape::_VertexProgramNoWave;
|
||||
drv->activeVertexProgram(program);
|
||||
CWaterModel::_WaterMat.setTexture(0, shape->_BumpMap[0]);
|
||||
CWaterModel::_WaterMat.setTexture(1, shape->_BumpMap[1]);
|
||||
CWaterModel::_WaterMat.setTexture(3, shape->_ColorMap);
|
||||
|
@ -953,25 +954,21 @@ void CWaterModel::setupMaterialNVertexShader(IDriver *drv, CWaterShape *shape, c
|
|||
{
|
||||
// setup 2x3 matrix for lookup in diffuse map
|
||||
updateDiffuseMapMatrix();
|
||||
cst[11].set(_ColorMapMatColumn0.x, _ColorMapMatColumn1.x, 0, _ColorMapMatColumn0.x * obsPos.x + _ColorMapMatColumn1.x * obsPos.y + _ColorMapMatPos.x);
|
||||
cst[12].set(_ColorMapMatColumn0.y, _ColorMapMatColumn1.y, 0, _ColorMapMatColumn0.y * obsPos.x + _ColorMapMatColumn1.y * obsPos.y + _ColorMapMatPos.y);
|
||||
drv->setUniform4f(IDriver::VertexProgram, program->idx().DiffuseMapVector0, _ColorMapMatColumn0.x, _ColorMapMatColumn1.x, 0, _ColorMapMatColumn0.x * obsPos.x + _ColorMapMatColumn1.x * obsPos.y + _ColorMapMatPos.x);
|
||||
drv->setUniform4f(IDriver::VertexProgram, program->idx().DiffuseMapVector1, _ColorMapMatColumn0.y, _ColorMapMatColumn1.y, 0, _ColorMapMatColumn0.y * obsPos.x + _ColorMapMatColumn1.y * obsPos.y + _ColorMapMatPos.y);
|
||||
}
|
||||
/// set matrix
|
||||
drv->setConstantMatrix(0, IDriver::ModelViewProjection, IDriver::Identity);
|
||||
// set builtins
|
||||
drv->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::ModelViewProjection), IDriver::ModelViewProjection, IDriver::Identity);
|
||||
drv->setUniformFog(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::Fog));
|
||||
// retrieve current time
|
||||
double date = scene->getCurrentTime();
|
||||
// set bumpmaps pos
|
||||
cst[6].set(fmodf(obsPos.x * shape->_HeightMapScale[0].x, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[0].x, 1), fmodf(shape->_HeightMapScale[0].y * obsPos.y, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[0].y, 1), 0.f, 1.f); // bump map 0 offset
|
||||
cst[5].set(shape->_HeightMapScale[0].x, shape->_HeightMapScale[0].y, 0, 0); // bump map 0 scale
|
||||
cst[8].set(fmodf(shape->_HeightMapScale[1].x * obsPos.x, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[1].x, 1), fmodf(shape->_HeightMapScale[1].y * obsPos.y, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[1].y, 1), 0.f, 1.f); // bump map 1 offset
|
||||
cst[7].set(shape->_HeightMapScale[1].x, shape->_HeightMapScale[1].y, 0, 0); // bump map 1 scale
|
||||
cst[9].set(0, 0, obsPos.z - zHeight, 1.f);
|
||||
cst[10].set(0.5f, 0.5f, 0.f, 1.f); // used to scale reflected ray into the envmap
|
||||
/// set all our constants in one call
|
||||
drv->setConstant(cstOffset, sizeof(cst) / sizeof(cst[0]) - cstOffset, (float *) &cst[cstOffset]);
|
||||
shape->initVertexProgram();
|
||||
drv->activeVertexProgram(shape->_ColorMap ? CWaterShape::_VertexProgramNoWaveDiffuse.get() : CWaterShape::_VertexProgramNoWave.get());
|
||||
drv->setConstantFog(4);
|
||||
drv->setUniform4f(IDriver::VertexProgram, program->idx().BumpMap0Offset, fmodf(obsPos.x * shape->_HeightMapScale[0].x, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[0].x, 1), fmodf(shape->_HeightMapScale[0].y * obsPos.y, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[0].y, 1), 0.f, 1.f); // bump map 0 offset
|
||||
drv->setUniform4f(IDriver::VertexProgram, program->idx().BumpMap0Scale, shape->_HeightMapScale[0].x, shape->_HeightMapScale[0].y, 0, 0); // bump map 0 scale
|
||||
drv->setUniform4f(IDriver::VertexProgram, program->idx().BumpMap1Offset, fmodf(shape->_HeightMapScale[1].x * obsPos.x, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[1].x, 1), fmodf(shape->_HeightMapScale[1].y * obsPos.y, 1.f) + (float) fmod(date * shape->_HeightMapSpeed[1].y, 1), 0.f, 1.f); // bump map 1 offset
|
||||
drv->setUniform4f(IDriver::VertexProgram, program->idx().BumpMap1Scale, shape->_HeightMapScale[1].x, shape->_HeightMapScale[1].y, 0, 0); // bump map 1 scale
|
||||
drv->setUniform4f(IDriver::VertexProgram, program->idx().ObserverHeight, 0, 0, obsPos.z - zHeight, 1.f);
|
||||
drv->setUniform4f(IDriver::VertexProgram, program->idx().ScaleReflectedRay, 0.5f, 0.5f, 0.f, 1.f); // used to scale reflected ray into the envmap
|
||||
}
|
||||
|
||||
//================================================
|
||||
|
@ -1363,7 +1360,7 @@ uint CWaterModel::getNumWantedVertices()
|
|||
uint CWaterModel::fillVB(void *datas, uint startTri, IDriver &drv)
|
||||
{
|
||||
H_AUTO( NL3D_Water_Render );
|
||||
if (drv.isWaterShaderSupported())
|
||||
if (drv.supportWaterShader())
|
||||
{
|
||||
return fillVBHard(datas, startTri);
|
||||
}
|
||||
|
@ -1657,7 +1654,7 @@ void CWaterModel::traverseRender()
|
|||
drv->setupModelMatrix(modelMat);
|
||||
bool isAbove = obsPos.z > getWorldMatrix().getPos().z;
|
||||
CVertexBuffer &vb = renderTrav.Scene->getWaterVB();
|
||||
if (drv->isWaterShaderSupported())
|
||||
if (drv->supportWaterShader())
|
||||
{
|
||||
setupMaterialNVertexShader(drv, shape, obsPos, isAbove, zHeight);
|
||||
nlassert(vb.getNumVertices() > 0);
|
||||
|
|
|
@ -81,7 +81,69 @@ DP4 o[TEX3].x, v[0], c[11]; #compute uv for diffuse texture \n\
|
|||
DP4 o[TEX3].y, v[0], c[12]; \n\
|
||||
END";
|
||||
|
||||
CVertexProgramWaterVPNoWave::CVertexProgramWaterVPNoWave(bool diffuse)
|
||||
{
|
||||
m_Diffuse = diffuse;
|
||||
// nelvp
|
||||
{
|
||||
CSource *source = new CSource();
|
||||
source->Profile = nelvp;
|
||||
source->DisplayName = "WaterVPNoWave/nelvp";
|
||||
source->ParamIndices["modelViewProjection"] = 0;
|
||||
source->ParamIndices["fog"] = 4;
|
||||
source->ParamIndices["bumpMap0Scale"] = 5;
|
||||
source->ParamIndices["bumpMap0Offset"] = 6;
|
||||
source->ParamIndices["bumpMap1Scale"] = 7;
|
||||
source->ParamIndices["bumpMap1Offset"] = 8;
|
||||
source->ParamIndices["observerHeight"] = 9;
|
||||
source->ParamIndices["scaleReflectedRay"] = 10;
|
||||
if (diffuse)
|
||||
{
|
||||
source->DisplayName += "/diffuse";
|
||||
source->ParamIndices["diffuseMapVector0"] = 11;
|
||||
source->ParamIndices["diffuseMapVector1"] = 12;
|
||||
source->setSourcePtr(WaterVPNoWaveDiffuse);
|
||||
}
|
||||
else
|
||||
{
|
||||
source->setSourcePtr(WaterVPNoWave);
|
||||
}
|
||||
addSource(source);
|
||||
}
|
||||
// glsl330v
|
||||
{
|
||||
// TODO_VP_GLSL
|
||||
// CSource *source = new CSource();
|
||||
// source->Profile = glsl330v;
|
||||
// source->DisplayName = "WaterVPNoWave/glsl330v";
|
||||
// if (diffuse) source->DisplayName += "/diffuse";
|
||||
// source->setSource...
|
||||
// addSource(source);
|
||||
}
|
||||
}
|
||||
|
||||
void CVertexProgramWaterVPNoWave::buildInfo()
|
||||
{
|
||||
m_Idx.BumpMap0Scale = getUniformIndex("bumpMap0Scale");
|
||||
nlassert(m_Idx.BumpMap0Scale != ~0);
|
||||
m_Idx.BumpMap0Offset = getUniformIndex("bumpMap0Offset");
|
||||
nlassert(m_Idx.BumpMap0Offset != ~0);
|
||||
m_Idx.BumpMap1Scale = getUniformIndex("bumpMap1Scale");
|
||||
nlassert(m_Idx.BumpMap1Scale != ~0);
|
||||
m_Idx.BumpMap1Offset = getUniformIndex("bumpMap1Offset");
|
||||
nlassert(m_Idx.BumpMap1Offset != ~0);
|
||||
m_Idx.ObserverHeight = getUniformIndex("observerHeight");
|
||||
nlassert(m_Idx.ObserverHeight != ~0);
|
||||
m_Idx.ScaleReflectedRay = getUniformIndex("scaleReflectedRay");
|
||||
nlassert(m_Idx.ScaleReflectedRay != ~0);
|
||||
if (m_Diffuse)
|
||||
{
|
||||
m_Idx.DiffuseMapVector0 = getUniformIndex("diffuseMapVector0");
|
||||
nlassert(m_Idx.DiffuseMapVector0 != ~0);
|
||||
m_Idx.DiffuseMapVector1 = getUniformIndex("diffuseMapVector1");
|
||||
nlassert(m_Idx.DiffuseMapVector1 != ~0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////
|
||||
// WAVY WATER //
|
||||
|
@ -188,15 +250,15 @@ uint32 CWaterShape::_XGridBorder = 4;
|
|||
uint32 CWaterShape::_YGridBorder = 4;
|
||||
uint32 CWaterShape::_MaxGridSize;
|
||||
bool CWaterShape::_GridSizeTouched = true;
|
||||
std::auto_ptr<CVertexProgram> CWaterShape::_VertexProgramBump1;
|
||||
std::auto_ptr<CVertexProgram> CWaterShape::_VertexProgramBump2;
|
||||
std::auto_ptr<CVertexProgram> CWaterShape::_VertexProgramBump1Diffuse;
|
||||
std::auto_ptr<CVertexProgram> CWaterShape::_VertexProgramBump2Diffuse;
|
||||
std::auto_ptr<CVertexProgram> CWaterShape::_VertexProgramNoBump;
|
||||
std::auto_ptr<CVertexProgram> CWaterShape::_VertexProgramNoBumpDiffuse;
|
||||
NLMISC::CSmartPtr<CVertexProgram> CWaterShape::_VertexProgramBump1;
|
||||
NLMISC::CSmartPtr<CVertexProgram> CWaterShape::_VertexProgramBump2;
|
||||
NLMISC::CSmartPtr<CVertexProgram> CWaterShape::_VertexProgramBump1Diffuse;
|
||||
NLMISC::CSmartPtr<CVertexProgram> CWaterShape::_VertexProgramBump2Diffuse;
|
||||
NLMISC::CSmartPtr<CVertexProgram> CWaterShape::_VertexProgramNoBump;
|
||||
NLMISC::CSmartPtr<CVertexProgram> CWaterShape::_VertexProgramNoBumpDiffuse;
|
||||
// water with no waves
|
||||
std::auto_ptr<CVertexProgram> CWaterShape::_VertexProgramNoWave;
|
||||
std::auto_ptr<CVertexProgram> CWaterShape::_VertexProgramNoWaveDiffuse;
|
||||
NLMISC::CSmartPtr<CVertexProgramWaterVPNoWave> CWaterShape::_VertexProgramNoWave;
|
||||
NLMISC::CSmartPtr<CVertexProgramWaterVPNoWave> CWaterShape::_VertexProgramNoWaveDiffuse;
|
||||
|
||||
|
||||
/** Build a vertex program for water depending on requirements
|
||||
|
@ -223,6 +285,7 @@ static CVertexProgram *BuildWaterVP(bool diffuseMap, bool bumpMap, bool use2Bump
|
|||
|
||||
vp += "\nEND";
|
||||
return new CVertexProgram(vp.c_str());
|
||||
// TODO_VP_GLSL
|
||||
}
|
||||
|
||||
|
||||
|
@ -321,17 +384,17 @@ void CWaterShape::initVertexProgram()
|
|||
if (!created)
|
||||
{
|
||||
// waves
|
||||
_VertexProgramBump1 = std::auto_ptr<CVertexProgram>(BuildWaterVP(false, true, false));
|
||||
_VertexProgramBump2 = std::auto_ptr<CVertexProgram>(BuildWaterVP(false, true, true));
|
||||
_VertexProgramBump1 = BuildWaterVP(false, true, false);
|
||||
_VertexProgramBump2 = BuildWaterVP(false, true, true);
|
||||
|
||||
_VertexProgramBump1Diffuse = std::auto_ptr<CVertexProgram>(BuildWaterVP(true, true, false));
|
||||
_VertexProgramBump2Diffuse = std::auto_ptr<CVertexProgram>(BuildWaterVP(true, true, true));
|
||||
_VertexProgramBump1Diffuse = BuildWaterVP(true, true, false);
|
||||
_VertexProgramBump2Diffuse = BuildWaterVP(true, true, true);
|
||||
|
||||
_VertexProgramNoBump = std::auto_ptr<CVertexProgram>(BuildWaterVP(false, false, false));
|
||||
_VertexProgramNoBumpDiffuse = std::auto_ptr<CVertexProgram>(BuildWaterVP(true, false, false));
|
||||
_VertexProgramNoBump = BuildWaterVP(false, false, false);
|
||||
_VertexProgramNoBumpDiffuse = BuildWaterVP(true, false, false);
|
||||
// no waves
|
||||
_VertexProgramNoWave.reset(new CVertexProgram(WaterVPNoWave));
|
||||
_VertexProgramNoWaveDiffuse.reset(new CVertexProgram(WaterVPNoWaveDiffuse));
|
||||
_VertexProgramNoWave = new CVertexProgramWaterVPNoWave(false);
|
||||
_VertexProgramNoWaveDiffuse = new CVertexProgramWaterVPNoWave(true); // TODO_VP_GLSL
|
||||
created = true;
|
||||
}
|
||||
}
|
||||
|
@ -372,7 +435,7 @@ void CWaterShape::flushTextures (IDriver &driver, uint selectedTexture)
|
|||
|
||||
/*
|
||||
if (
|
||||
(driver.supportTextureShaders() && driver.isTextureAddrModeSupported(CMaterial::OffsetTexture))
|
||||
(driver.supportTextureShaders() && driver.supportTextureAddrMode(CMaterial::OffsetTexture))
|
||||
|| driver.supportEMBM()
|
||||
)
|
||||
{
|
||||
|
|
85
code/ryzom/client/src/camera.cpp
Normal file
85
code/ryzom/client/src/camera.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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/misc/types_nl.h>
|
||||
#include "camera.h"
|
||||
|
||||
#include <nel/3d/stereo_display.h>
|
||||
|
||||
#include "global.h"
|
||||
#include "misc.h"
|
||||
|
||||
using namespace NLMISC;
|
||||
using namespace NL3D;
|
||||
|
||||
//---------------------------------------------------
|
||||
// update the camera perspective setup
|
||||
//---------------------------------------------------
|
||||
void updateCameraPerspective()
|
||||
{
|
||||
float fov, aspectRatio;
|
||||
computeCurrentFovAspectRatio(fov, aspectRatio);
|
||||
|
||||
// change the perspective of the scene
|
||||
if(!MainCam.empty())
|
||||
MainCam.setPerspective(fov, aspectRatio, CameraSetupZNear, ClientCfg.Vision);
|
||||
// change the perspective of the root scene
|
||||
if(SceneRoot)
|
||||
{
|
||||
UCamera cam= SceneRoot->getCam();
|
||||
cam.setPerspective(fov, aspectRatio, SceneRootCameraZNear, SceneRootCameraZFar);
|
||||
}
|
||||
}
|
||||
|
||||
void buildCameraClippingPyramid(std::vector<CPlane> &planes)
|
||||
{
|
||||
if (StereoDisplay) StereoDisplay->getClippingFrustum(0, &MainCam);
|
||||
|
||||
// Compute pyramid in view basis.
|
||||
CVector pfoc(0,0,0);
|
||||
const CFrustum &frustum = MainCam.getFrustum();
|
||||
InvMainSceneViewMatrix = MainCam.getMatrix();
|
||||
MainSceneViewMatrix = InvMainSceneViewMatrix;
|
||||
MainSceneViewMatrix.invert();
|
||||
|
||||
CVector lb(frustum.Left, frustum.Near, frustum.Bottom );
|
||||
CVector lt(frustum.Left, frustum.Near, frustum.Top );
|
||||
CVector rb(frustum.Right, frustum.Near, frustum.Bottom );
|
||||
CVector rt(frustum.Right, frustum.Near, frustum.Top );
|
||||
|
||||
CVector lbFar(frustum.Left, ClientCfg.CharacterFarClip, frustum.Bottom);
|
||||
CVector ltFar(frustum.Left, ClientCfg.CharacterFarClip, frustum.Top );
|
||||
CVector rtFar(frustum.Right, ClientCfg.CharacterFarClip, frustum.Top );
|
||||
|
||||
planes.resize (4);
|
||||
// planes[0].make(lbFar, ltFar, rtFar);
|
||||
planes[0].make(pfoc, lt, lb);
|
||||
planes[1].make(pfoc, rt, lt);
|
||||
planes[2].make(pfoc, rb, rt);
|
||||
planes[3].make(pfoc, lb, rb);
|
||||
|
||||
// Compute pyramid in World basis.
|
||||
// The vector transformation M of a plane p is computed as p*M-1.
|
||||
// Here, ViewMatrix== CamMatrix-1. Hence the following formula.
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
planes[i] = planes[i]*MainSceneViewMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
/* end of file */
|
29
code/ryzom/client/src/camera.h
Normal file
29
code/ryzom/client/src/camera.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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 CL_CAMERA_H
|
||||
#define CL_CAMERA_H
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
#include <nel/misc/plane.h>
|
||||
|
||||
void updateCameraPerspective();
|
||||
void buildCameraClippingPyramid(std::vector<NLMISC::CPlane> &planes);
|
||||
|
||||
#endif // CL_CAMERA_H
|
||||
|
||||
/* end of file */
|
|
@ -302,6 +302,10 @@ CClientConfig::CClientConfig()
|
|||
Contrast = 0.f; // Default Monitor Contrast.
|
||||
Luminosity = 0.f; // Default Monitor Luminosity.
|
||||
Gamma = 0.f; // Default Monitor Gamma.
|
||||
|
||||
VREnable = false;
|
||||
VRDisplayDevice = "Auto";
|
||||
VRDisplayDeviceId = "";
|
||||
|
||||
Local = false; // Default is Net Mode.
|
||||
FSHost = ""; // Default Host.
|
||||
|
@ -847,6 +851,9 @@ void CClientConfig::setValues()
|
|||
else
|
||||
cfgWarning ("Default value used for 'Driver3D' !!!");
|
||||
|
||||
READ_BOOL_FV(VREnable)
|
||||
READ_STRING_FV(VRDisplayDevice)
|
||||
READ_STRING_FV(VRDisplayDeviceId)
|
||||
|
||||
////////////
|
||||
// INPUTS //
|
||||
|
|
|
@ -146,6 +146,11 @@ struct CClientConfig
|
|||
/// Monitor Gamma [-1 ~ 1], default 0
|
||||
float Gamma;
|
||||
|
||||
// VR
|
||||
bool VREnable;
|
||||
std::string VRDisplayDevice;
|
||||
std::string VRDisplayDeviceId;
|
||||
|
||||
/// Client in Local mode or not.
|
||||
bool Local;
|
||||
/// Host.
|
||||
|
|
|
@ -84,7 +84,65 @@ static const char *DecalAttenuationVertexProgramCode =
|
|||
MUL o[COL0].w, v[3], R0.w; \n\
|
||||
END \n";
|
||||
|
||||
static NL3D::CVertexProgram DecalAttenuationVertexProgram(DecalAttenuationVertexProgramCode);
|
||||
class CVertexProgramDecalAttenuation : public CVertexProgram
|
||||
{
|
||||
public:
|
||||
struct CIdx
|
||||
{
|
||||
// 0-3 mvp
|
||||
uint WorldToUV0; // 4
|
||||
uint WorldToUV1; // 5
|
||||
uint RefCamDist; // 6
|
||||
uint DistScaleBias; // 7
|
||||
uint Diffuse; // 8
|
||||
// 9
|
||||
// 10
|
||||
uint BlendScale; // 11
|
||||
};
|
||||
CVertexProgramDecalAttenuation()
|
||||
{
|
||||
// nelvp
|
||||
{
|
||||
CSource *source = new CSource();
|
||||
source->Profile = nelvp;
|
||||
source->DisplayName = "nelvp/DecalAttenuation";
|
||||
source->setSourcePtr(DecalAttenuationVertexProgramCode);
|
||||
source->ParamIndices["modelViewProjection"] = 0;
|
||||
source->ParamIndices["worldToUV0"] = 4;
|
||||
source->ParamIndices["worldToUV1"] = 5;
|
||||
source->ParamIndices["refCamDist"] = 6;
|
||||
source->ParamIndices["distScaleBias"] = 7;
|
||||
source->ParamIndices["diffuse"] = 8;
|
||||
source->ParamIndices["blendScale"] = 11;
|
||||
addSource(source);
|
||||
}
|
||||
// TODO_VP_GLSL
|
||||
}
|
||||
~CVertexProgramDecalAttenuation()
|
||||
{
|
||||
|
||||
}
|
||||
virtual void buildInfo()
|
||||
{
|
||||
m_Idx.WorldToUV0 = getUniformIndex("worldToUV0");
|
||||
nlassert(m_Idx.WorldToUV0 != ~0);
|
||||
m_Idx.WorldToUV1 = getUniformIndex("worldToUV1");
|
||||
nlassert(m_Idx.WorldToUV1 != ~0);
|
||||
m_Idx.RefCamDist = getUniformIndex("refCamDist");
|
||||
nlassert(m_Idx.RefCamDist != ~0);
|
||||
m_Idx.DistScaleBias = getUniformIndex("distScaleBias");
|
||||
nlassert(m_Idx.DistScaleBias != ~0);
|
||||
m_Idx.Diffuse = getUniformIndex("diffuse");
|
||||
nlassert(m_Idx.Diffuse != ~0);
|
||||
m_Idx.BlendScale = getUniformIndex("blendScale");
|
||||
nlassert(m_Idx.BlendScale != ~0);
|
||||
}
|
||||
inline const CIdx &idx() const { return m_Idx; }
|
||||
private:
|
||||
CIdx m_Idx;
|
||||
};
|
||||
|
||||
static NLMISC::CSmartPtr<CVertexProgramDecalAttenuation> DecalAttenuationVertexProgram;
|
||||
|
||||
|
||||
typedef CShadowPolyReceiver::CRGBAVertex CRGBAVertex;
|
||||
|
@ -92,6 +150,10 @@ typedef CShadowPolyReceiver::CRGBAVertex CRGBAVertex;
|
|||
// ****************************************************************************
|
||||
CDecal::CDecal()
|
||||
{
|
||||
if (!DecalAttenuationVertexProgram)
|
||||
{
|
||||
DecalAttenuationVertexProgram = new CVertexProgramDecalAttenuation();
|
||||
}
|
||||
_ShadowMap = new CShadowMap(&(((CSceneUser *) Scene)->getScene().getRenderTrav().getShadowMapManager()));
|
||||
_Material.initUnlit();
|
||||
_Diffuse = CRGBA::White;
|
||||
|
@ -303,6 +365,7 @@ void CDecal::renderTriCache(NL3D::IDriver &drv, NL3D::CShadowPolyReceiver &/*
|
|||
drv.setupModelMatrix(modelMat);
|
||||
if (useVertexProgram)
|
||||
{
|
||||
CVertexProgramDecalAttenuation *program = DecalAttenuationVertexProgram;
|
||||
{
|
||||
CVertexBufferReadWrite vba;
|
||||
_VB.setNumVertices((uint32)_TriCache.size());
|
||||
|
@ -310,16 +373,16 @@ void CDecal::renderTriCache(NL3D::IDriver &drv, NL3D::CShadowPolyReceiver &/*
|
|||
memcpy(vba.getVertexCoordPointer(), &_TriCache[0], sizeof(CRGBAVertex) * _TriCache.size());
|
||||
}
|
||||
drv.activeVertexBuffer(_VB);
|
||||
drv.setConstantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity);
|
||||
drv.setConstant(4, _WorldToUVMatrix[0][0], _WorldToUVMatrix[1][0], _WorldToUVMatrix[2][0], _WorldToUVMatrix[3][0]);
|
||||
drv.setConstant(5, _WorldToUVMatrix[0][1], _WorldToUVMatrix[1][1], _WorldToUVMatrix[2][1], _WorldToUVMatrix[3][1]);
|
||||
drv.setConstant(8, _Diffuse.R * (1.f / 255.f), _Diffuse.G * (1.f / 255.f), _Diffuse.B * (1.f / 255.f), 1.f);
|
||||
drv.setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CGPUProgramIndex::ModelViewProjection), NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity);
|
||||
drv.setUniform4f(IDriver::VertexProgram, program->idx().WorldToUV0, _WorldToUVMatrix[0][0], _WorldToUVMatrix[1][0], _WorldToUVMatrix[2][0], _WorldToUVMatrix[3][0]);
|
||||
drv.setUniform4f(IDriver::VertexProgram, program->idx().WorldToUV1, _WorldToUVMatrix[0][1], _WorldToUVMatrix[1][1], _WorldToUVMatrix[2][1], _WorldToUVMatrix[3][1]);
|
||||
drv.setUniform4f(IDriver::VertexProgram, program->idx().Diffuse, _Diffuse.R * (1.f / 255.f), _Diffuse.G * (1.f / 255.f), _Diffuse.B * (1.f / 255.f), 1.f);
|
||||
const NLMISC::CVector &camPos = MainCam.getMatrix().getPos();
|
||||
drv.setConstant(6, camPos.x - _RefPosition.x, camPos.y - _RefPosition.y, camPos.z - _RefPosition.z, 1.f);
|
||||
drv.setUniform4f(IDriver::VertexProgram, program->idx().RefCamDist, camPos.x - _RefPosition.x, camPos.y - _RefPosition.y, camPos.z - _RefPosition.z, 1.f);
|
||||
// bottom & top blend
|
||||
float bottomBlendScale = 1.f / favoid0(_BottomBlendZMax - _BottomBlendZMin);
|
||||
float topBlendScale = 1.f / favoid0(_TopBlendZMin - _TopBlendZMax);
|
||||
drv.setConstant(11, bottomBlendScale, bottomBlendScale * (_RefPosition.z - _BottomBlendZMin),
|
||||
drv.setUniform4f(IDriver::VertexProgram, program->idx().BlendScale, bottomBlendScale, bottomBlendScale * (_RefPosition.z - _BottomBlendZMin),
|
||||
topBlendScale, topBlendScale * (_RefPosition.z - _TopBlendZMax));
|
||||
//
|
||||
static volatile bool wantSimpleMat = false;
|
||||
|
@ -560,12 +623,12 @@ void CDecalRenderList::renderAllDecals()
|
|||
NL3D::IDriver *drvInternal = ((CDriverUser *) Driver)->getDriver();
|
||||
//
|
||||
static volatile bool forceNoVertexProgram = false;
|
||||
if (drvInternal->isVertexProgramSupported() && !forceNoVertexProgram)
|
||||
if (!forceNoVertexProgram && drvInternal->compileVertexProgram(DecalAttenuationVertexProgram))
|
||||
{
|
||||
//drvInternal->setConstantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity);
|
||||
drvInternal->setConstant(7, _DistScale, _DistBias, 0.f, 1.f);
|
||||
drvInternal->activeVertexProgram(DecalAttenuationVertexProgram);
|
||||
//drvInternal->setCons/tantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity);
|
||||
drvInternal->setUniform4f(IDriver::VertexProgram, DecalAttenuationVertexProgram->idx().DistScaleBias, _DistScale, _DistBias, 0.f, 1.f);
|
||||
useVertexProgram = true;
|
||||
drvInternal->activeVertexProgram(&DecalAttenuationVertexProgram);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -26,6 +26,8 @@ using namespace NLMISC;
|
|||
// ***************************************************************************
|
||||
// Main System
|
||||
NL3D::UDriver *Driver = 0; // The main 3D Driver
|
||||
NL3D::IStereoDisplay *StereoDisplay = NULL; // Stereo display
|
||||
NL3D::IStereoHMD *StereoHMD = NULL; // Head mount display
|
||||
CSoundManager *SoundMngr = 0; // the sound manager
|
||||
NL3D::UMaterial GenericMat; // Generic Material
|
||||
NL3D::UTextContext *TextContext = 0; // Context for all the text in the client.
|
||||
|
|
|
@ -40,6 +40,8 @@ namespace NL3D
|
|||
class UMaterial;
|
||||
class UTextContext;
|
||||
class UWaterEnvMap;
|
||||
class IStereoDisplay;
|
||||
class IStereoHMD;
|
||||
}
|
||||
|
||||
class CEntityAnimationManager;
|
||||
|
@ -77,6 +79,8 @@ const float ExtraZoneLoadingVision = 100.f;
|
|||
// ***************************************************************************
|
||||
// Main System
|
||||
extern NL3D::UDriver *Driver; // The main 3D Driver
|
||||
extern NL3D::IStereoDisplay *StereoDisplay; // Stereo display
|
||||
extern NL3D::IStereoHMD *StereoHMD; // Head mount display
|
||||
extern CSoundManager *SoundMngr; // the sound manager
|
||||
extern NL3D::UMaterial GenericMat; // Generic Material
|
||||
extern NL3D::UTextContext *TextContext; // Context for all the text in the client.
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "nel/3d/u_driver.h"
|
||||
#include "nel/3d/u_text_context.h"
|
||||
#include "nel/3d/u_shape_bank.h"
|
||||
#include "nel/3d/stereo_hmd.h"
|
||||
// Net.
|
||||
#include "nel/net/email.h"
|
||||
// Ligo.
|
||||
|
@ -46,6 +47,7 @@
|
|||
|
||||
// Std.
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
// Game Share
|
||||
#include "game_share/ryzom_version.h"
|
||||
// Client
|
||||
|
@ -792,6 +794,59 @@ void prelogInit()
|
|||
// Check driver version
|
||||
checkDriverVersion();
|
||||
|
||||
// Initialize the VR devices (even more important than the most important part of the client)
|
||||
nmsg = "Initializing VR devices...";
|
||||
ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
|
||||
if (ClientCfg.VREnable)
|
||||
{
|
||||
nldebug("VR [C]: Enabled");
|
||||
std::vector<NL3D::CStereoDeviceInfo> devices;
|
||||
IStereoDisplay::listDevices(devices);
|
||||
for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it)
|
||||
{
|
||||
std::stringstream name;
|
||||
name << std::string("[") << it->Serial << "] [" << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName << "]";
|
||||
nlinfo("VR [C]: Stereo Display: %s", name.str().c_str());
|
||||
}
|
||||
CStereoDeviceInfo *deviceInfo = NULL;
|
||||
if (ClientCfg.VRDisplayDevice == std::string("Auto")
|
||||
&& devices.begin() != devices.end())
|
||||
{
|
||||
deviceInfo = &devices[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it)
|
||||
{
|
||||
std::stringstream name;
|
||||
name << IStereoDisplay::getLibraryName(it->Library) << " - " << it->Manufacturer << " - " << it->ProductName;
|
||||
if (name.str() == ClientCfg.VRDisplayDevice)
|
||||
deviceInfo = &(*it);
|
||||
if (ClientCfg.VRDisplayDeviceId == it->Serial)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (deviceInfo)
|
||||
{
|
||||
nlinfo("VR [C]: Create VR stereo display device");
|
||||
StereoDisplay = IStereoDisplay::createDevice(*deviceInfo);
|
||||
if (StereoDisplay)
|
||||
{
|
||||
if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD)
|
||||
{
|
||||
nlinfo("VR [C]: Stereo display device is a HMD");
|
||||
StereoHMD = static_cast<IStereoHMD *>(StereoDisplay);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nldebug("VR [C]: NOT Enabled");
|
||||
}
|
||||
IStereoDisplay::releaseUnusedLibraries();
|
||||
|
||||
|
||||
// Create the driver (most important part of the client).
|
||||
nmsg = "Creating 3d driver...";
|
||||
ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
|
||||
|
@ -860,6 +915,11 @@ void prelogInit()
|
|||
Driver->setSwapVBLInterval(1);
|
||||
else
|
||||
Driver->setSwapVBLInterval(0);
|
||||
|
||||
if (StereoDisplay)
|
||||
{
|
||||
// override mode TODO
|
||||
}
|
||||
|
||||
// Set the mode of the window.
|
||||
if (!Driver->setDisplay (mode, false))
|
||||
|
@ -1102,6 +1162,12 @@ void prelogInit()
|
|||
|
||||
// init bloom effect
|
||||
CBloomEffect::getInstance().init(driver != UDriver::Direct3d);
|
||||
|
||||
if (StereoDisplay)
|
||||
{
|
||||
// Init stereo display resources
|
||||
StereoDisplay->setDriver(Driver);
|
||||
}
|
||||
|
||||
nlinfo ("PROFILE: %d seconds for prelogInit", (uint32)(ryzomGetLocalTime ()-initStart)/1000);
|
||||
|
||||
|
|
|
@ -542,10 +542,12 @@ void renderSceneScreenShot (uint left, uint right, uint top, uint bottom, uint s
|
|||
{
|
||||
CCameraBackup cbScene = setupCameraForScreenshot(*Scene, left, right, top, bottom, screenShotWidth, screenShotHeight);
|
||||
CCameraBackup cbCanopy = setupCameraForScreenshot(*SceneRoot, left, right, top, bottom, screenShotWidth, screenShotHeight);
|
||||
commitCamera();
|
||||
// sky setup are copied from main scene before rendering so no setup done here
|
||||
renderAll(ClientCfg.ScreenShotFullDetail);
|
||||
renderScene(ClientCfg.ScreenShotFullDetail, ClientCfg.Bloom);
|
||||
restoreCamera(*Scene, cbScene);
|
||||
restoreCamera(*SceneRoot, cbCanopy);
|
||||
commitCamera();
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
|
|
@ -95,11 +95,11 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
// renderAll is called in main loop. It can called beginRenderLandscapePolyPart and renderLandscapePolyPart
|
||||
// renderScene is called in main loop. It can called beginRenderLandscapePolyPart and renderLandscapePolyPart
|
||||
// methods.
|
||||
friend void renderAll(bool);
|
||||
friend void renderScene();
|
||||
|
||||
// Enable stencil test and initialize function and operation of stencil at the beginning of renderAll method,
|
||||
// Enable stencil test and initialize function and operation of stencil at the beginning of renderScene method,
|
||||
// before opaque render of canopy and main scene parts.
|
||||
// The eighth bit will be written with a 0 during next render to mark stencil buffer parts which will
|
||||
// support Shadow Volume algorithm.
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -29,9 +29,13 @@ const uint NUM_MISSION_OPTIONS = 8;
|
|||
bool mainLoop();
|
||||
|
||||
// render all
|
||||
void renderAll(bool forceFullDetail = false);
|
||||
void renderScene();
|
||||
void renderScene(bool forceFullDetail, bool bloom);
|
||||
void setDefaultChatWindow(CChatWindow *defaultChatWindow);
|
||||
|
||||
// Commit sky scene camera for rendering
|
||||
void commitCamera();
|
||||
|
||||
void updateDayNightCycleHour();
|
||||
|
||||
|
||||
|
|
774
code/ryzom/client/src/main_loop_debug.cpp
Normal file
774
code/ryzom/client/src/main_loop_debug.cpp
Normal file
|
@ -0,0 +1,774 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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/misc/types_nl.h>
|
||||
#include "main_loop_debug.h"
|
||||
|
||||
#include <nel/3d/u_text_context.h>
|
||||
#include <nel/gui/lua_ihm.h>
|
||||
|
||||
#include "game_share/ryzom_version.h"
|
||||
|
||||
#include "global.h"
|
||||
#include "client_cfg.h"
|
||||
#include "user_entity.h"
|
||||
#include "debug_client.h"
|
||||
#include "entities.h"
|
||||
#include "motion/user_controls.h"
|
||||
#include "pacs_client.h"
|
||||
#include "sound_manager.h"
|
||||
#include "view.h"
|
||||
#include "prim_file.h"
|
||||
#include "weather.h"
|
||||
#include "light_cycle_manager.h"
|
||||
#include "net_manager.h"
|
||||
#include "ping.h"
|
||||
#include "world_database_manager.h"
|
||||
#include "continent_manager.h"
|
||||
#include "client_sheets/weather_function_params_sheet.h"
|
||||
#include "weather_manager_client.h"
|
||||
#include "fog_map.h"
|
||||
#include "misc.h"
|
||||
#include "interface_v3/interface_manager.h"
|
||||
|
||||
using namespace NLMISC;
|
||||
using namespace NL3D;
|
||||
using namespace NLGUI;
|
||||
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
|
||||
extern std::set<std::string> LodCharactersNotFound;
|
||||
extern uint32 NbDatabaseChanges;
|
||||
extern CFogState MainFogState;
|
||||
extern CPing Ping;
|
||||
extern bool Filter3D[RYZOM_MAX_FILTER_3D];
|
||||
|
||||
//namespace /* anonymous */ {
|
||||
|
||||
NLMISC::CValueSmoother smoothFPS;
|
||||
NLMISC::CValueSmoother moreSmoothFPS(64);
|
||||
|
||||
//} /* anonymous namespace */
|
||||
|
||||
//---------------------------------------------------
|
||||
// displayDebug :
|
||||
// Display some debug infos.
|
||||
//---------------------------------------------------
|
||||
void displayDebug()
|
||||
{
|
||||
float lineStep = ClientCfg.DebugLineStep;
|
||||
float line;
|
||||
|
||||
// Initialize Pen //
|
||||
//----------------//
|
||||
// Create a shadow when displaying a text.
|
||||
TextContext->setShaded(true);
|
||||
// Set the font size.
|
||||
TextContext->setFontSize(ClientCfg.DebugFontSize);
|
||||
// Set the text color
|
||||
TextContext->setColor(ClientCfg.DebugFontColor);
|
||||
|
||||
// TOP LEFT //
|
||||
//----------//
|
||||
TextContext->setHotSpot(UTextContext::TopLeft);
|
||||
line = 0.9f;
|
||||
// FPS and Ms per frame
|
||||
{
|
||||
// smooth across frames.
|
||||
double deltaTime = smoothFPS.getSmoothValue ();
|
||||
// FPS and Ms per frame
|
||||
if(deltaTime != 0.f)
|
||||
TextContext->printfAt(0.f, line,"%.1f fps", 1.f/deltaTime);
|
||||
else
|
||||
TextContext->printfAt(0.f, line,"%.1f fps", 0.f);
|
||||
TextContext->printfAt(0.1f, line, "%d ms", (uint)(deltaTime*1000));
|
||||
}
|
||||
line -= lineStep;
|
||||
line -= lineStep;
|
||||
|
||||
// USER
|
||||
// Front
|
||||
TextContext->printfAt(0.0f, line, " %f (%f,%f,%f) front", atan2(UserEntity->front().y, UserEntity->front().x), UserEntity->front().x, UserEntity->front().y, UserEntity->front().z);
|
||||
line -= lineStep;
|
||||
// Dir
|
||||
TextContext->printfAt(0.0f, line, " %f (%f,%f,%f) dir", atan2(UserEntity->dir().y, UserEntity->dir().x), UserEntity->dir().x, UserEntity->dir().y, UserEntity->dir().z);
|
||||
line -= lineStep;
|
||||
// NB Stage
|
||||
TextContext->printfAt(0.0f, line, " NB Stage: %d", UserEntity->nbStage());
|
||||
line -= lineStep;
|
||||
// NB Animation FXs still remaining in the remove list.
|
||||
TextContext->printfAt(0.0f, line, " NB FXs to remove: %d", UserEntity->nbAnimFXToRemove());
|
||||
line -= lineStep;
|
||||
// Mode.
|
||||
TextContext->printfAt(0.0f, line, " Mode: %d (%s)", (sint)UserEntity->mode(), MBEHAV::modeToString(UserEntity->mode()).c_str());
|
||||
line -= lineStep;
|
||||
// Behaviour.
|
||||
TextContext->printfAt(0.0f, line, " Behaviour: %d (%s)", (sint)UserEntity->behaviour(), MBEHAV::behaviourToString(UserEntity->behaviour()).c_str());
|
||||
line -= lineStep;
|
||||
// Display the target mount.
|
||||
TextContext->printfAt(0.0f, line, " Mount: %d", UserEntity->mount());
|
||||
line -= lineStep;
|
||||
// Display the target rider.
|
||||
TextContext->printfAt(0.0f, line, " Rider: %d", UserEntity->rider());
|
||||
line -= lineStep;
|
||||
// Display the current animation name.
|
||||
TextContext->printfAt(0.0f, line, " Current Animation Name: %s", UserEntity->currentAnimationName().c_str());
|
||||
line -= lineStep;
|
||||
// Display the current move animation set name.
|
||||
TextContext->printfAt(0.0f, line, " Current AnimationSet Name (MOVE): %s", UserEntity->currentAnimationSetName(MOVE).c_str());
|
||||
line -= lineStep;
|
||||
// Display Missing Animations
|
||||
if(::CAnimation::MissingAnim.empty() == false)
|
||||
{
|
||||
TextContext->printfAt(0.0f, line, " '%u' Missing Animations, 1st: '%s'", ::CAnimation::MissingAnim.size(), (*(::CAnimation::MissingAnim.begin())).c_str());
|
||||
line -= lineStep;
|
||||
}
|
||||
// Display Missing LoD
|
||||
if(LodCharactersNotFound.empty() == false)
|
||||
{
|
||||
TextContext->printfAt(0.0f, line, " '%u' Missing LoD, 1st: '%s'", LodCharactersNotFound.size(), (*(LodCharactersNotFound.begin())).c_str());
|
||||
line -= lineStep;
|
||||
}
|
||||
|
||||
// Watched Entity
|
||||
line -= lineStep;
|
||||
// Now Displaying the selection.
|
||||
TextContext->printfAt(0.0f, line, "--*** Watched entity ***--");
|
||||
line -= lineStep;
|
||||
// Display information about the debug entity slot.
|
||||
if(WatchedEntitySlot != CLFECOMMON::INVALID_SLOT)
|
||||
{
|
||||
// Get a pointer on the target.
|
||||
CEntityCL *watchedEntity = EntitiesMngr.entity(WatchedEntitySlot);
|
||||
if(watchedEntity)
|
||||
{
|
||||
// Display Debug Information about the Selection.
|
||||
watchedEntity->displayDebug(0.0f, line, -lineStep);
|
||||
|
||||
// Distance of the target
|
||||
CVectorD diffvector = UserEntity->pos() - watchedEntity->pos();
|
||||
TextContext->printfAt(0.0f, line, " Distance: %10.2f (Manhattan: %.2f)", diffvector.norm(), fabs(diffvector.x) + fabs(diffvector.y) );
|
||||
line -= lineStep;
|
||||
}
|
||||
// Target not allocated
|
||||
else
|
||||
{
|
||||
TextContext->printfAt(0.0f, line, "Not allocated (%d)", WatchedEntitySlot);
|
||||
line -= lineStep;
|
||||
}
|
||||
}
|
||||
// No Target
|
||||
else
|
||||
{
|
||||
TextContext->printfAt(0.0f, line, "None");
|
||||
line -= lineStep;
|
||||
}
|
||||
|
||||
/* Ca rame grave !
|
||||
|
||||
uint nMem = NLMEMORY::GetAllocatedMemory();
|
||||
line -= lineStep;
|
||||
TextContext->printfAt(0.0f, line, "Mem Used: %d",nMem);*/
|
||||
|
||||
// 3D Filters information:
|
||||
#ifdef _PROFILE_ON_
|
||||
line-= lineStep;
|
||||
TextContext->printfAt(0.0f, line, "3D Filters:");
|
||||
line-= lineStep;
|
||||
TextContext->printfAt(0.0f, line, "MeshNoVP: %s", Filter3D[FilterMeshNoVP]?"Ok":"NOT RENDERED!");
|
||||
line-= lineStep;
|
||||
TextContext->printfAt(0.0f, line, "MeshVP: %s", Filter3D[FilterMeshVP]?"Ok":"NOT RENDERED!");
|
||||
line-= lineStep;
|
||||
TextContext->printfAt(0.0f, line, "FXs: %s", Filter3D[FilterFXs]?"Ok":"NOT RENDERED!");
|
||||
line-= lineStep;
|
||||
if (Landscape)
|
||||
{
|
||||
TextContext->printfAt(0.0f, line, "Landscape: %s", Filter3D[FilterLandscape]?"Ok":"NOT RENDERED!");
|
||||
line-= lineStep;
|
||||
}
|
||||
else
|
||||
{
|
||||
TextContext->printfAt(0.0f, line, "Landscape not enabled");
|
||||
}
|
||||
TextContext->printfAt(0.0f, line, "Vegetable: %s", Filter3D[FilterVegetable]?"Ok":"NOT RENDERED!");
|
||||
line-= lineStep;
|
||||
TextContext->printfAt(0.0f, line, "Skeleton: %s", Filter3D[FilterSkeleton]?"Ok":"NOT RENDERED!");
|
||||
line-= lineStep;
|
||||
TextContext->printfAt(0.0f, line, "Water: %s", Filter3D[FilterWater]?"Ok":"NOT RENDERED!");
|
||||
line-= lineStep;
|
||||
TextContext->printfAt(0.0f, line, "Cloud: %s", Filter3D[FilterCloud]?"Ok":"NOT RENDERED!");
|
||||
line-= lineStep;
|
||||
TextContext->printfAt(0.0f, line, "CoarseMesh: %s", Filter3D[FilterCoarseMesh]?"Ok":"NOT RENDERED!");
|
||||
line-= lineStep;
|
||||
TextContext->printfAt(0.0f, line, "Sky: %s", Filter3D[FilterSky]?"Ok":"NOT RENDERED!");
|
||||
line-= lineStep;
|
||||
// Materials Infos
|
||||
TextContext->printfAt(0.0f, line, "SetupedMatrix: %d", Driver->profileSetupedModelMatrix() );
|
||||
line-= lineStep;
|
||||
TextContext->printfAt(0.0f, line, "SetupedMaterials: %d", Driver->profileSetupedMaterials() );
|
||||
line-= lineStep;
|
||||
// Display camera cluster system
|
||||
TextContext->printfAt(0.0f, line, "ClusterSystem: %p", MainCam.getClusterSystem() );
|
||||
line-= 2 * lineStep;
|
||||
// Lua stuffs
|
||||
CInterfaceManager *pIM = CInterfaceManager::getInstance();
|
||||
TextContext->printfAt(0.0f, line, "Lua mem (kb) : %d / %d", CLuaManager::getInstance().getLuaState()->getGCCount(), CLuaManager::getInstance().getLuaState()->getGCThreshold());
|
||||
line-= lineStep;
|
||||
TextContext->printfAt(0.0f, line, "Lua stack size = %d", CLuaManager::getInstance().getLuaState()->getTop());
|
||||
line-= lineStep;
|
||||
|
||||
#endif
|
||||
|
||||
// TOP LEFT //
|
||||
//-----------//
|
||||
TextContext->setHotSpot(UTextContext::TopLeft);
|
||||
line = 1.f;
|
||||
string str;
|
||||
#if FINAL_VERSION
|
||||
str = "FV";
|
||||
#else
|
||||
str = "DEV";
|
||||
#endif
|
||||
if(ClientCfg.ExtendedCommands)
|
||||
str += "_E";
|
||||
str += " "RYZOM_VERSION;
|
||||
TextContext->printfAt(0.f, line, "Version %s", str.c_str());
|
||||
|
||||
// TOP MIDDLE //
|
||||
//------------//
|
||||
TextContext->setHotSpot(UTextContext::MiddleTop);
|
||||
line = 1.f;
|
||||
// Motion Mode
|
||||
TextContext->printfAt(0.5f, line, "%s", UserControls.modeStr().c_str());
|
||||
line -= lineStep;
|
||||
|
||||
// TOP RIGHT //
|
||||
//-----------//
|
||||
TextContext->setHotSpot(UTextContext::TopRight);
|
||||
line = 1.f;
|
||||
//// 3D Infos
|
||||
// Video mem allocated.
|
||||
TextContext->printfAt(1.f, line, "Video mem. : %f", Driver->profileAllocatedTextureMemory()/(1024.f*1024.f));
|
||||
line -= lineStep;
|
||||
// Video mem used since last swapBuffers().
|
||||
TextContext->printfAt(1.f, line, "Video mem. since last swap buffer: %f", Driver->getUsedTextureMemory()/(1024.f*1024.f));
|
||||
line -= lineStep;
|
||||
// Get the last face count asked from the main scene before reduction.
|
||||
TextContext->printfAt(1.f, line, "Nb Skin Face Asked: %f", Scene->getGroupNbFaceAsked("Skin"));
|
||||
line -= lineStep;
|
||||
TextContext->printfAt(1.f, line, "Nb Fx Face Asked: %f", Scene->getGroupNbFaceAsked("Fx"));
|
||||
line -= lineStep;
|
||||
// All Triangles In
|
||||
CPrimitiveProfile pIn;
|
||||
CPrimitiveProfile pOut;
|
||||
Driver->profileRenderedPrimitives(pIn, pOut);
|
||||
TextContext->printfAt(1.f, line, "Tri In : %d", pIn.NTriangles+2*pIn.NQuads);
|
||||
line -= lineStep;
|
||||
// All Triangles Out
|
||||
TextContext->printfAt(1.f, line, "Tri Out : %d", pOut.NTriangles+2*pIn.NQuads);
|
||||
line -= lineStep;
|
||||
// Current Cluster
|
||||
string strPos;
|
||||
// Check there is a PACS Primitive before using it.
|
||||
if(UserEntity->getPrimitive() && GR)
|
||||
{
|
||||
UGlobalPosition gPos;
|
||||
UserEntity->getPrimitive()->getGlobalPosition(gPos, dynamicWI);
|
||||
string strPos = GR->getIdentifier(gPos);
|
||||
}
|
||||
else
|
||||
strPos = "No Primitive";
|
||||
TextContext->printfAt(1.f, line, "Cluster : %s", strPos.c_str());
|
||||
line -= lineStep;
|
||||
//// SOUND Infos
|
||||
line -= lineStep;
|
||||
if(SoundMngr)
|
||||
{
|
||||
TextContext->printfAt(1.f, line, "Sound source instance: %u", SoundMngr->getSourcesInstanceCount());
|
||||
line -= lineStep;
|
||||
TextContext->printfAt(1.f, line, "Logical playing SoundSource: %u", SoundMngr->getMixer()->getPlayingSourcesCount ());
|
||||
line -= lineStep;
|
||||
TextContext->printfAt(1.f, line, "Audio tracks: %u/%u", SoundMngr->getMixer()->getUsedTracksCount(), SoundMngr->getMixer()->getPolyphony());
|
||||
line -= lineStep;
|
||||
if (SoundMngr->getMixer()->getMutedPlayingSourcesCount() > 0)
|
||||
{
|
||||
TextContext->printfAt(1.f, line, "Source muted: %u !", SoundMngr->getMixer()->getMutedPlayingSourcesCount());
|
||||
line -= lineStep;
|
||||
}
|
||||
TextContext->printfAt(1.f, line, "Samples in memory: %g MB", SoundMngr->getLoadingSamplesSize() / (1024.0f*1024.0f));
|
||||
line -= lineStep;
|
||||
|
||||
}
|
||||
|
||||
// BOTTOM RIGHT //
|
||||
//--------------//
|
||||
TextContext->setHotSpot(UTextContext::BottomRight);
|
||||
line = 0.f;
|
||||
//// POSITION
|
||||
CVector postmp = View.viewPos();
|
||||
// Pos
|
||||
TextContext->printfAt(1.f, line, "Position : %d %d %d",(int)postmp.x,(int)postmp.y,(int)postmp.z);
|
||||
line += lineStep;
|
||||
// Body Heading
|
||||
TextContext->printfAt(1.f, line, "Front : %.2f %.2f %.2f", UserEntity->front().x, UserEntity->front().y, UserEntity->front().z);
|
||||
line += lineStep;
|
||||
// Speed
|
||||
TextContext->printfAt(1.f, line, "Speed : %.2f", (float) UserEntity->speed());
|
||||
line += lineStep;
|
||||
// Zone
|
||||
if (!ClientCfg.Light)
|
||||
{
|
||||
if (Landscape)
|
||||
{
|
||||
TextContext->printfAt(1.f, line, "Zone: %s", Landscape->getZoneName(postmp).c_str());
|
||||
line += lineStep;
|
||||
}
|
||||
}
|
||||
// Prim File
|
||||
string primFile = PrimFiles.getCurrentPrimitive ();
|
||||
if (!primFile.empty ())
|
||||
{
|
||||
TextContext->printfAt(1.f, line, "Prim File: %s", primFile.c_str ());
|
||||
line += lineStep;
|
||||
}
|
||||
|
||||
//// CONNECTION
|
||||
line += lineStep;
|
||||
// Ryzom Day.
|
||||
TextContext->printfAt(1.f, line, "Ryzom Day : %d", RT.getRyzomDay());
|
||||
line += lineStep;
|
||||
// hour in the game
|
||||
float dayNightCycleHour = (float)RT.getRyzomTime();
|
||||
TextContext->printfAt(1.f, line, "Ryzom Time : %2u:%02u", int(dayNightCycleHour), int((dayNightCycleHour-int(dayNightCycleHour))*60.0f));
|
||||
line += lineStep;
|
||||
// light hour in the game, used to display te day/night
|
||||
TextContext->printfAt(1.f, line, "Ryzom Light Time : %2u:%02u (%s)", int(DayNightCycleHour), int((DayNightCycleHour-int(DayNightCycleHour))*60.0f), LightCycleManager.getStateString().c_str());
|
||||
line += lineStep;
|
||||
// Server GameCycle
|
||||
TextContext->printfAt(1.f, line, "Server GameCycle : %u", (uint)NetMngr.getCurrentServerTick());
|
||||
line += lineStep;
|
||||
// Current GameCycle
|
||||
TextContext->printfAt(1.f, line, "Current GameCycle : %u", (uint)NetMngr.getCurrentClientTick());
|
||||
line += lineStep;
|
||||
// Current GameCycle
|
||||
TextContext->printfAt(1.f, line, "Ms per Cycle : %d", NetMngr.getMsPerTick());
|
||||
line += lineStep;
|
||||
// Packet Loss
|
||||
TextContext->printfAt(1.f, line, "Packet Loss : %.1f %%", NetMngr.getMeanPacketLoss()*100.0f);
|
||||
line += lineStep;
|
||||
// Packet Loss
|
||||
TextContext->printfAt(1.f, line, "Packets Lost : %u", NetMngr.getTotalLostPackets());
|
||||
line += lineStep;
|
||||
// Mean Upload
|
||||
TextContext->printfAt(1.f, line, "Mean Upld : %.3f kbps", NetMngr.getMeanUpload());
|
||||
line += lineStep;
|
||||
// Mean Download
|
||||
TextContext->printfAt(1.f, line, "Mean Dnld : %.3f kbps", NetMngr.getMeanDownload());
|
||||
line += lineStep;
|
||||
|
||||
// Mean Download
|
||||
TextContext->printfAt(1.f, line, "Nb in Vision : %d(%d,%d,%d)",
|
||||
EntitiesMngr.nbEntitiesAllocated(),
|
||||
EntitiesMngr.nbUser(),
|
||||
EntitiesMngr.nbPlayer(),
|
||||
EntitiesMngr.nbChar());
|
||||
line += lineStep;
|
||||
|
||||
// Number of database changes
|
||||
TextContext->printfAt(1.f, line, "DB Changes : %u", NbDatabaseChanges );
|
||||
line += lineStep;
|
||||
|
||||
// Ping
|
||||
TextContext->printfAt(1.f, line, "DB Ping : %u ms", Ping.getValue());
|
||||
line += lineStep;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Manual weather setup
|
||||
{
|
||||
if(ContinentMngr.cur()) // Only usable if there is a continent loaded.
|
||||
{
|
||||
if (!ForceTrueWeatherValue)
|
||||
{
|
||||
const CWeatherFunction &wf = ContinentMngr.cur()->WeatherFunction[CurrSeason];
|
||||
float wv;
|
||||
if (ClientCfg.ManualWeatherSetup)
|
||||
{
|
||||
wv = std::max(wf.getNumWeatherSetups() - 1, 0u) * ManualWeatherValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
wv = std::max(wf.getNumWeatherSetups() - 1, 0u) * ::getBlendedWeather(RT.getRyzomDay(), RT.getRyzomTime(), *WeatherFunctionParams, ContinentMngr.cur()->WeatherFunction);
|
||||
}
|
||||
const CWeatherSetup *ws = wf.getWeatherSetup((uint) floorf(wv));
|
||||
std::string name0 = ws ? NLMISC::CStringMapper::unmap(ws->SetupName) : "???";
|
||||
ws = wf.getWeatherSetup(std::min((uint) (floorf(wv) + 1), wf.getNumWeatherSetups() - 1));
|
||||
std::string name1 = ws ? NLMISC::CStringMapper::unmap(ws->SetupName) : "???";
|
||||
TextContext->printfAt(1.f, line, "Weather value : %.02f : %s -> %s", ws ? wv : 0.f, name0.c_str(), name1.c_str());
|
||||
line += lineStep;
|
||||
}
|
||||
else
|
||||
{
|
||||
TextContext->printfAt(1.f, line, "Weather value : %.02f", WeatherManager.getWeatherValue() * std::max(ContinentMngr.cur()->WeatherFunction[CurrSeason].getNumWeatherSetups() - 1, 0u));
|
||||
line += lineStep;
|
||||
TextContext->printfAt(1.f, line, "TEST WEATHER FUNCTION");
|
||||
line += lineStep;
|
||||
}
|
||||
// season
|
||||
TextContext->printfAt(1.f, line, "Season : %s", EGSPD::CSeason::toString(CurrSeason).c_str());
|
||||
line += lineStep;
|
||||
}
|
||||
}
|
||||
|
||||
// fog dist
|
||||
if (ContinentMngr.cur())
|
||||
{
|
||||
TextContext->printfAt(1.f, line, "Continent fog min near = %.1f, max far = %.1f", ContinentMngr.cur()->FogStart, ContinentMngr.cur()->FogEnd);
|
||||
line += lineStep;
|
||||
CFogState tmpFog;
|
||||
ContinentMngr.getFogState(MainFog, LightCycleManager.getLightLevel(), LightCycleManager.getLightDesc().DuskRatio, LightCycleManager.getState(), View.viewPos(), tmpFog);
|
||||
TextContext->printfAt(1.f, line, "Continent fog curr near = %.1f, curr far = %.1f", tmpFog.FogStartDist, tmpFog.FogEndDist);
|
||||
line += lineStep;
|
||||
}
|
||||
const CWeatherState &ws = WeatherManager.getCurrWeatherState();
|
||||
TextContext->printfAt(1.f, line, "Weather fog near = %.1f, far = %.1f", ws.FogNear[MainFog], ws.FogFar[MainFog]);
|
||||
line += lineStep;
|
||||
TextContext->printfAt(1.f, line, "Final fog near = %.1f, far = %.1f", MainFogState.FogStartDist, MainFogState.FogEndDist);
|
||||
line += lineStep;
|
||||
float left, right, bottom, top, znear, zfar;
|
||||
Scene->getCam().getFrustum(left, right, bottom, top, znear, zfar);
|
||||
TextContext->printfAt(1.f, line, "Clip near = %.1f, far = %.1f", znear, zfar);
|
||||
line += lineStep;
|
||||
|
||||
// Connection states
|
||||
TextContext->printfAt(1.f, line, "State : %s", NetMngr.getConnectionStateCStr() );
|
||||
line += lineStep;
|
||||
|
||||
// UGlobalPosition globalPos;
|
||||
// UserEntity->getPrimitive()->getGlobalPosition(globalPos, dynamicWI);
|
||||
// uint32 material = GR->getMaterial( globalPos );
|
||||
// TextContext->printfAt(0.5f,0.5f,"Material : %d Gpos=(inst=%d,surf=%d,x=%.2f,y=%.2f",material, globalPos.InstanceId, globalPos.LocalPosition.Surface, globalPos.LocalPosition.Estimation.x, globalPos.LocalPosition.Estimation.y);
|
||||
|
||||
// No more shadow when displaying a text.
|
||||
TextContext->setShaded(false);
|
||||
}// displayDebug //
|
||||
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
|
||||
//---------------------------------------------------
|
||||
// displayDebug :
|
||||
// Display some debug infos.
|
||||
//---------------------------------------------------
|
||||
void displayDebugFps()
|
||||
{
|
||||
float lineStep = ClientCfg.DebugLineStep;
|
||||
float line;
|
||||
|
||||
// Initialize Pen //
|
||||
//----------------//
|
||||
// Create a shadow when displaying a text.
|
||||
TextContext->setShaded(true);
|
||||
// Set the font size.
|
||||
TextContext->setFontSize(ClientCfg.DebugFontSize);
|
||||
// Set the text color
|
||||
TextContext->setColor(ClientCfg.DebugFontColor);
|
||||
|
||||
// TOP LEFT //
|
||||
//----------//
|
||||
TextContext->setHotSpot(UTextContext::TopLeft);
|
||||
line = 0.9f;
|
||||
// Ms per frame
|
||||
{
|
||||
float spf = smoothFPS.getSmoothValue ();
|
||||
// Ms per frame
|
||||
TextContext->printfAt(0.1f, line, "FPS %.1f ms - %.1f fps", spf*1000, 1.f/spf);
|
||||
line-= lineStep;
|
||||
// More Smoothed Ms per frame
|
||||
spf = moreSmoothFPS.getSmoothValue ();
|
||||
TextContext->printfAt(0.1f, line, "Smoothed FPS %.1f ms - %.1f fps", spf*1000, 1.f/spf);
|
||||
line-= lineStep;
|
||||
}
|
||||
}
|
||||
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
|
||||
static NLMISC::CRefPtr<CInterfaceElement> HighlightedDebugUI;
|
||||
|
||||
// displayDebug :
|
||||
// Display information about ui elements that are under the mouse
|
||||
//---------------------------------------------------
|
||||
void displayDebugUIUnderMouse()
|
||||
{
|
||||
float lineStep = ClientCfg.DebugLineStep;
|
||||
float line;
|
||||
|
||||
// Initialize Pen //
|
||||
//----------------//
|
||||
// Create a shadow when displaying a text.
|
||||
TextContext->setShaded(true);
|
||||
// Set the font size.
|
||||
TextContext->setFontSize(ClientCfg.DebugFontSize);
|
||||
|
||||
|
||||
|
||||
// TOP LEFT //
|
||||
//----------//
|
||||
TextContext->setHotSpot(UTextContext::TopLeft);
|
||||
line = 0.9f;
|
||||
|
||||
CInterfaceManager *pIM = CInterfaceManager::getInstance();
|
||||
// for now only accessible with R2ED
|
||||
if (ClientCfg.R2EDEnabled)
|
||||
{
|
||||
TextContext->setColor(CRGBA::Cyan);
|
||||
TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+A) to cycle prev");
|
||||
line-= lineStep;
|
||||
TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+Q) to cycle next");
|
||||
line-= lineStep;
|
||||
TextContext->printfAt(0.1f, line, "Press default key (ctrl+shift+W) to inspect element");
|
||||
line-= 2 * lineStep;
|
||||
}
|
||||
//
|
||||
const std::vector<CCtrlBase *> &rICL = CWidgetManager::getInstance()->getCtrlsUnderPointer ();
|
||||
const std::vector<CInterfaceGroup *> &rIGL = CWidgetManager::getInstance()->getGroupsUnderPointer ();
|
||||
// If previous highlighted element is found in the list, then keep it, else reset to first element
|
||||
if (std::find(rICL.begin(), rICL.end(), HighlightedDebugUI) == rICL.end() &&
|
||||
std::find(rIGL.begin(), rIGL.end(), HighlightedDebugUI) == rIGL.end())
|
||||
{
|
||||
if (!rICL.empty())
|
||||
{
|
||||
HighlightedDebugUI = rICL[0];
|
||||
}
|
||||
else
|
||||
if (!rIGL.empty())
|
||||
{
|
||||
HighlightedDebugUI = rIGL[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
HighlightedDebugUI = NULL;
|
||||
}
|
||||
}
|
||||
//
|
||||
TextContext->setColor(CRGBA::Green);
|
||||
TextContext->printfAt(0.1f, line, "Controls under cursor ");
|
||||
line -= lineStep * 1.4f;
|
||||
TextContext->printfAt(0.1f, line, "----------------------");
|
||||
line -= lineStep;
|
||||
for(uint k = 0; k < rICL.size(); ++k)
|
||||
{
|
||||
if (rICL[k])
|
||||
{
|
||||
TextContext->setColor(rICL[k] != HighlightedDebugUI ? ClientCfg.DebugFontColor : CRGBA::Red);
|
||||
TextContext->printfAt(0.1f, line, "id = %s, address = 0x%p, parent = 0x%p", rICL[k]->getId().c_str(), rICL[k], rICL[k]->getParent());
|
||||
}
|
||||
else
|
||||
{
|
||||
TextContext->setColor(CRGBA::Blue);
|
||||
TextContext->printfAt(0.1f, line, "<NULL> control found !!!");
|
||||
}
|
||||
line-= lineStep;
|
||||
}
|
||||
//
|
||||
TextContext->setColor(CRGBA::Green);
|
||||
TextContext->printfAt(0.1f, line, "Groups under cursor ");
|
||||
line -= lineStep * 1.4f;
|
||||
TextContext->printfAt(0.1f, line, "----------------------");
|
||||
line-= lineStep;
|
||||
for(uint k = 0; k < rIGL.size(); ++k)
|
||||
{
|
||||
if (rIGL[k])
|
||||
{
|
||||
TextContext->setColor(rIGL[k] != HighlightedDebugUI ? ClientCfg.DebugFontColor : CRGBA::Red);
|
||||
TextContext->printfAt(0.1f, line, "id = %s, address = 0x%p, parent = 0x%p", rIGL[k]->getId().c_str(), rIGL[k], rIGL[k]->getParent());
|
||||
}
|
||||
else
|
||||
{
|
||||
TextContext->setColor(CRGBA::Blue);
|
||||
TextContext->printfAt(0.1f, line, "<NULL> group found !!!");
|
||||
}
|
||||
line-= lineStep;
|
||||
}
|
||||
}
|
||||
|
||||
// get all element under the mouse in a single vector
|
||||
static void getElementsUnderMouse(std::vector<CInterfaceElement *> &ielem)
|
||||
{
|
||||
CInterfaceManager *pIM = CInterfaceManager::getInstance();
|
||||
const std::vector<CCtrlBase *> &rICL = CWidgetManager::getInstance()->getCtrlsUnderPointer();
|
||||
const std::vector<CInterfaceGroup *> &rIGL = CWidgetManager::getInstance()->getGroupsUnderPointer();
|
||||
ielem.clear();
|
||||
ielem.insert(ielem.end(), rICL.begin(), rICL.end());
|
||||
ielem.insert(ielem.end(), rIGL.begin(), rIGL.end());
|
||||
}
|
||||
|
||||
class CHandlerDebugUiPrevElementUnderMouse : public IActionHandler
|
||||
{
|
||||
virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
|
||||
{
|
||||
std::vector<CInterfaceElement *> ielem;
|
||||
getElementsUnderMouse(ielem);
|
||||
for(uint k = 0; k < ielem.size(); ++k)
|
||||
{
|
||||
if (HighlightedDebugUI == ielem[k])
|
||||
{
|
||||
HighlightedDebugUI = ielem[k == 0 ? ielem.size() - 1 : k - 1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
REGISTER_ACTION_HANDLER( CHandlerDebugUiPrevElementUnderMouse, "debug_ui_prev_element_under_mouse");
|
||||
|
||||
class CHandlerDebugUiNextElementUnderMouse : public IActionHandler
|
||||
{
|
||||
virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
|
||||
{
|
||||
std::vector<CInterfaceElement *> ielem;
|
||||
getElementsUnderMouse(ielem);
|
||||
for(uint k = 0; k < ielem.size(); ++k)
|
||||
{
|
||||
if (HighlightedDebugUI == ielem[k])
|
||||
{
|
||||
HighlightedDebugUI = ielem[(k + 1) % ielem.size()];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
REGISTER_ACTION_HANDLER( CHandlerDebugUiNextElementUnderMouse, "debug_ui_next_element_under_mouse");
|
||||
|
||||
class CHandlerDebugUiDumpElementUnderMouse : public IActionHandler
|
||||
{
|
||||
virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
|
||||
{
|
||||
if (HighlightedDebugUI == NULL) return;
|
||||
CLuaState *lua = CLuaManager::getInstance().getLuaState();
|
||||
if (!lua) return;
|
||||
CLuaStackRestorer lsr(lua, 0);
|
||||
CLuaIHM::pushUIOnStack(*lua, HighlightedDebugUI);
|
||||
lua->pushGlobalTable();
|
||||
CLuaObject env(*lua);
|
||||
env["inspect"].callNoThrow(1, 0);
|
||||
}
|
||||
};
|
||||
REGISTER_ACTION_HANDLER( CHandlerDebugUiDumpElementUnderMouse, "debug_ui_inspect_element_under_mouse");
|
||||
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
|
||||
//-----------------------------------------------
|
||||
// Macro to Display a Text
|
||||
//-----------------------------------------------
|
||||
#define DISP_TEXT(x, text) \
|
||||
/* Display the text at the right place */ \
|
||||
TextContext->printfAt(x, line, text); \
|
||||
/* Change the line */ \
|
||||
line += lineStep; \
|
||||
|
||||
//---------------------------------------------------
|
||||
// displayHelp :
|
||||
// Display an Help.
|
||||
//---------------------------------------------------
|
||||
void displayHelp()
|
||||
{
|
||||
float line = 1.f;
|
||||
float lineStep = -ClientCfg.HelpLineStep;
|
||||
|
||||
// Create a shadow when displaying a text.
|
||||
TextContext->setShaded(true);
|
||||
// Set the font size.
|
||||
TextContext->setFontSize(ClientCfg.HelpFontSize);
|
||||
// Set the text color
|
||||
TextContext->setColor(ClientCfg.HelpFontColor);
|
||||
|
||||
|
||||
line = 1.f;
|
||||
TextContext->setHotSpot(UTextContext::TopLeft);
|
||||
DISP_TEXT(0.0f, "SHIFT + F1 : This Menu")
|
||||
DISP_TEXT(0.0f, "SHIFT + F2 : Display Debug Infos")
|
||||
DISP_TEXT(0.0f, "SHIFT + F3 : Wire mode");
|
||||
DISP_TEXT(0.0f, "SHIFT + F4 : Do not Render the Scene");
|
||||
DISP_TEXT(0.0f, "SHIFT + F5 : Toogle Display OSD interfaces");
|
||||
// DISP_TEXT(0.0f, "SHIFT + F6 : Not used");
|
||||
DISP_TEXT(0.0f, "SHIFT + F7 : Compass Mode (User/Camera)");
|
||||
DISP_TEXT(0.0f, "SHIFT + F8 : Camera Mode (INSERT to change your position)");
|
||||
DISP_TEXT(0.0f, "SHIFT + F9 : Free Mouse");
|
||||
DISP_TEXT(0.0f, "SHIFT + F10 : Take a Screen Shot (+CTRL) for jpg");
|
||||
// DISP_TEXT(0.0f, "SHIFT + F11 : Test");
|
||||
DISP_TEXT(0.0f, "SHIFT + ESCAPE : Quit");
|
||||
DISP_TEXT(0.0f, "SHIFT + C : First/Third Person View");
|
||||
|
||||
line = 1.f;
|
||||
TextContext->setHotSpot(UTextContext::TopRight);
|
||||
DISP_TEXT(1.0f, "UP : FORWARD");
|
||||
DISP_TEXT(1.0f, "DOWN : BACKWARD");
|
||||
DISP_TEXT(1.0f, "LEFT : ROTATE LEFT");
|
||||
DISP_TEXT(1.0f, "RIGHT : ROTATE RIGHT");
|
||||
DISP_TEXT(1.0f, "CTRL + LEFT : STRAFE LEFT");
|
||||
DISP_TEXT(1.0f, "CTRL + RIGHT : STRAFE RIGHT");
|
||||
DISP_TEXT(1.0f, "END : Auto Walk");
|
||||
DISP_TEXT(1.0f, "DELETE : Walk/Run");
|
||||
DISP_TEXT(1.0f, "PG UP : Look Up");
|
||||
DISP_TEXT(1.0f, "PG DOWN : Look Down");
|
||||
// DISP_TEXT(1.0f, "CTRL + I : Inventory");
|
||||
// DISP_TEXT(1.0f, "CTRL + C : Spells composition interface");
|
||||
// DISP_TEXT(1.0f, "CTRL + S : Memorized Spells interface");
|
||||
DISP_TEXT(1.0f, "CTRL + B : Show/Hide PACS Borders");
|
||||
DISP_TEXT(1.0f, "CTRL + P : Player target himself");
|
||||
DISP_TEXT(1.0f, "CTRL + D : Unselect target");
|
||||
DISP_TEXT(1.0f, "CTRL + TAB : Next Chat Mode (say/shout");
|
||||
DISP_TEXT(1.0f, "CTRL + R : Reload Client.cfg File");
|
||||
// DISP_TEXT(1.0f, "CTRL + N : Toggle Night / Day lighting");
|
||||
DISP_TEXT(1.0f, "CTRL + F2 : Profile on / off");
|
||||
DISP_TEXT(1.0f, "CTRL + F3 : Movie Shooter record / stop");
|
||||
DISP_TEXT(1.0f, "CTRL + F4 : Movie Shooter replay");
|
||||
DISP_TEXT(1.0f, "CTRL + F5 : Movie Shooter save");
|
||||
#ifndef NL_USE_DEFAULT_MEMORY_MANAGER
|
||||
DISP_TEXT(1.0f, "CTRL + F6 : Save memory stat report");
|
||||
#endif // NL_USE_DEFAULT_MEMORY_MANAGER
|
||||
DISP_TEXT(1.0f, "CTRL + F7 : Show / hide prim file");
|
||||
DISP_TEXT(1.0f, "CTRL + F8 : Change prim file UP");
|
||||
DISP_TEXT(1.0f, "CTRL + F9 : Change prim file DOWN");
|
||||
|
||||
// No more shadow when displaying a text.
|
||||
TextContext->setShaded(false);
|
||||
}// displayHelp //
|
||||
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
|
||||
/* end of file */
|
31
code/ryzom/client/src/main_loop_debug.h
Normal file
31
code/ryzom/client/src/main_loop_debug.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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 CL_MAIN_LOOP_DEBUG_H
|
||||
#define CL_MAIN_LOOP_DEBUG_H
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// Display some debug infos.
|
||||
void displayDebug();
|
||||
void displayDebugFps();
|
||||
void displayDebugUIUnderMouse();
|
||||
// Display an Help.
|
||||
void displayHelp();
|
||||
|
||||
#endif // CL_MAIN_LOOP_DEBUG_H
|
||||
|
||||
/* end of file */
|
226
code/ryzom/client/src/main_loop_temp.cpp
Normal file
226
code/ryzom/client/src/main_loop_temp.cpp
Normal file
|
@ -0,0 +1,226 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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/misc/types_nl.h>
|
||||
#include "main_loop_temp.h"
|
||||
|
||||
#include "global.h"
|
||||
|
||||
// tempDumpValidPolys
|
||||
#include <nel/gui/interface_element.h>
|
||||
#include <nel/gui/ctrl_polygon.h>
|
||||
#include "interface_v3/interface_manager.h"
|
||||
|
||||
// tempDumpColPolys
|
||||
#include <nel/3d/packed_world.h>
|
||||
#include "r2/editor.h"
|
||||
#include "user_entity.h"
|
||||
#include <nel/3d/driver_user.h>
|
||||
|
||||
using namespace NLMISC;
|
||||
using namespace NL3D;
|
||||
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
|
||||
// TMP TMP
|
||||
void tempDumpValidPolys()
|
||||
{
|
||||
struct CPolyDisp : public CInterfaceElementVisitor
|
||||
{
|
||||
virtual void visitCtrl(CCtrlBase *ctrl)
|
||||
{
|
||||
CCtrlPolygon *cp = dynamic_cast<CCtrlPolygon *>(ctrl);
|
||||
if (cp)
|
||||
{
|
||||
sint32 cornerX, cornerY;
|
||||
cp->getParent()->getCorner(cornerX, cornerY, cp->getParentPosRef());
|
||||
for(sint32 y = 0; y < (sint32) Screen.getHeight(); ++y)
|
||||
{
|
||||
for(sint32 x = 0; x < (sint32) Screen.getWidth(); ++x)
|
||||
{
|
||||
if (cp->contains(CVector2f((float) (x - cornerX), (float) (y - cornerY))))
|
||||
{
|
||||
((CRGBA *) &Screen.getPixels()[0])[x + (Screen.getHeight() - 1 - y) * Screen.getWidth()] = CRGBA::Magenta;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CBitmap Screen;
|
||||
} polyDisp;
|
||||
Driver->getBuffer(polyDisp.Screen);
|
||||
CInterfaceManager::getInstance()->visit(&polyDisp);
|
||||
COFile output("poly.tga");
|
||||
polyDisp.Screen.writeTGA(output);
|
||||
}
|
||||
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
|
||||
// TMP TMP
|
||||
static void viewportToScissor(const CViewport &vp, CScissor &scissor)
|
||||
{
|
||||
scissor.X = vp.getX();
|
||||
scissor.Y = vp.getY();
|
||||
scissor.Width = vp.getWidth();
|
||||
scissor.Height = vp.getHeight();
|
||||
}
|
||||
|
||||
// TMP TMP
|
||||
void tempDumpColPolys()
|
||||
{
|
||||
CPackedWorld *pw = R2::getEditor().getIslandCollision().getPackedIsland();
|
||||
if (pw)
|
||||
{
|
||||
static CMaterial material;
|
||||
static CMaterial wiredMaterial;
|
||||
static CMaterial texturedMaterial;
|
||||
static CVertexBuffer vb;
|
||||
static bool initDone = false;
|
||||
if (!initDone)
|
||||
{
|
||||
vb.setVertexFormat(CVertexBuffer::PositionFlag);
|
||||
vb.setPreferredMemory(CVertexBuffer::AGPVolatile, false);
|
||||
material.initUnlit();
|
||||
material.setDoubleSided(true);
|
||||
material.setZFunc(CMaterial::lessequal);
|
||||
wiredMaterial.initUnlit();
|
||||
wiredMaterial.setDoubleSided(true);
|
||||
wiredMaterial.setZFunc(CMaterial::lessequal);
|
||||
wiredMaterial.setColor(CRGBA(255, 255, 255, 250));
|
||||
wiredMaterial.texEnvOpAlpha(0, CMaterial::Replace);
|
||||
wiredMaterial.texEnvArg0Alpha(0, CMaterial::Diffuse, CMaterial::SrcAlpha);
|
||||
wiredMaterial.setBlend(true);
|
||||
wiredMaterial.setBlendFunc(CMaterial::srcalpha, CMaterial::invsrcalpha);
|
||||
texturedMaterial.initUnlit();
|
||||
texturedMaterial.setDoubleSided(true);
|
||||
texturedMaterial.setZFunc(CMaterial::lessequal);
|
||||
initDone = true;
|
||||
}
|
||||
// just add a projected texture
|
||||
R2::getEditor().getIslandCollision().loadEntryPoints();
|
||||
R2::CScenarioEntryPoints &sep = R2::CScenarioEntryPoints::getInstance();
|
||||
CVectorD playerPos = UserEntity->pos();
|
||||
R2::CScenarioEntryPoints::CCompleteIsland *island = sep.getCompleteIslandFromCoords(CVector2f((float) playerPos.x, (float) playerPos.y));
|
||||
static CSString currIsland;
|
||||
if (island && island->Island != currIsland)
|
||||
{
|
||||
currIsland = island->Island;
|
||||
CTextureFile *newTex = new CTextureFile(currIsland + "_sp.tga");
|
||||
newTex->setWrapS(ITexture::Clamp);
|
||||
newTex->setWrapT(ITexture::Clamp);
|
||||
texturedMaterial.setTexture(0, newTex);
|
||||
texturedMaterial.texEnvOpRGB(0, CMaterial::Replace);
|
||||
texturedMaterial.texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor);
|
||||
texturedMaterial.setTexCoordGen(0, true);
|
||||
texturedMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace);
|
||||
CMatrix mat;
|
||||
CVector scale((float) (island->XMax - island->XMin),
|
||||
(float) (island->YMax - island->YMin), 0.f);
|
||||
scale.x = 1.f / favoid0(scale.x);
|
||||
scale.y = 1.f / favoid0(scale.y);
|
||||
scale.z = 0.f;
|
||||
mat.setScale(scale);
|
||||
mat.setPos(CVector(- island->XMin * scale.x, - island->YMin * scale.y, 0.f));
|
||||
//
|
||||
CMatrix uvScaleMat;
|
||||
//
|
||||
uint texWidth = (uint) (island->XMax - island->XMin);
|
||||
uint texHeight = (uint) (island->YMax - island->YMin);
|
||||
float UScale = (float) texWidth / raiseToNextPowerOf2(texWidth);
|
||||
float VScale = (float) texHeight / raiseToNextPowerOf2(texHeight);
|
||||
//
|
||||
uvScaleMat.setScale(CVector(UScale, - VScale, 0.f));
|
||||
uvScaleMat.setPos(CVector(0.f, VScale, 0.f));
|
||||
//
|
||||
texturedMaterial.enableUserTexMat(0, true);
|
||||
texturedMaterial.setUserTexMat(0, uvScaleMat * mat);
|
||||
}
|
||||
const CFrustum &frust = MainCam.getFrustum();
|
||||
|
||||
//
|
||||
IDriver *driver = ((CDriverUser *) Driver)->getDriver();
|
||||
|
||||
driver->enableFog(true);
|
||||
const CRGBA clearColor = CRGBA(0, 0, 127, 0);
|
||||
driver->setupFog(frust.Far * 0.8f, frust.Far, clearColor);
|
||||
CViewport vp;
|
||||
vp.init(0.f, 0.f, 1.f, 1.f);
|
||||
driver->setupViewport(vp);
|
||||
CScissor scissor;
|
||||
viewportToScissor(vp, scissor);
|
||||
driver->setupScissor(scissor);
|
||||
//
|
||||
driver->setFrustum(frust.Left, frust.Right, frust.Bottom, frust.Top, frust.Near, frust.Far, frust.Perspective);
|
||||
driver->setupViewMatrix(MainCam.getMatrix().inverted());
|
||||
driver->setupModelMatrix(CMatrix::Identity);
|
||||
//
|
||||
//
|
||||
const CVector localFrustCorners[8] =
|
||||
{
|
||||
CVector(frust.Left, frust.Near, frust.Top),
|
||||
CVector(frust.Right, frust.Near, frust.Top),
|
||||
CVector(frust.Right, frust.Near, frust.Bottom),
|
||||
CVector(frust.Left, frust.Near, frust.Bottom),
|
||||
CVector(frust.Left * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near),
|
||||
CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near),
|
||||
CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near),
|
||||
CVector(frust.Left * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near)
|
||||
};
|
||||
// roughly compute covered zones
|
||||
//
|
||||
/*
|
||||
sint frustZoneMinX = INT_MAX;
|
||||
sint frustZoneMaxX = INT_MIN;
|
||||
sint frustZoneMinY = INT_MAX;
|
||||
sint frustZoneMaxY = INT_MIN;
|
||||
for(uint k = 0; k < sizeofarray(localFrustCorners); ++k)
|
||||
{
|
||||
CVector corner = camMat * localFrustCorners[k];
|
||||
sint zoneX = (sint) (corner.x / 160.f) - zoneMinX;
|
||||
sint zoneY = (sint) floorf(corner.y / 160.f) - zoneMinY;
|
||||
frustZoneMinX = std::min(frustZoneMinX, zoneX);
|
||||
frustZoneMinY = std::min(frustZoneMinY, zoneY);
|
||||
frustZoneMaxX = std::max(frustZoneMaxX, zoneX);
|
||||
frustZoneMaxY = std::max(frustZoneMaxY, zoneY);
|
||||
}
|
||||
*/
|
||||
|
||||
const uint TRI_BATCH_SIZE = 10000; // batch size for rendering
|
||||
static std::vector<TPackedZoneBaseSPtr> zones;
|
||||
zones.clear();
|
||||
pw->getZones(zones);
|
||||
for(uint k = 0; k < zones.size(); ++k)
|
||||
{
|
||||
zones[k]->render(vb, *driver, texturedMaterial, wiredMaterial, MainCam.getMatrix(), TRI_BATCH_SIZE, localFrustCorners);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
// ********************************************************************
|
||||
|
||||
/* end of file */
|
30
code/ryzom/client/src/main_loop_temp.h
Normal file
30
code/ryzom/client/src/main_loop_temp.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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 CL_MAIN_LOOP_TEMP_H
|
||||
#define CL_MAIN_LOOP_TEMP_H
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// TMP TMP
|
||||
void tempDumpValidPolys();
|
||||
|
||||
// TMP TMP
|
||||
void tempDumpColPolys();
|
||||
|
||||
#endif // CL_MAIN_LOOP_TEMP_H
|
||||
|
||||
/* end of file */
|
341
code/ryzom/client/src/main_loop_utilities.cpp
Normal file
341
code/ryzom/client/src/main_loop_utilities.cpp
Normal file
|
@ -0,0 +1,341 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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/misc/types_nl.h>
|
||||
#include "main_loop_utilities.h"
|
||||
|
||||
#include <nel/3d/u_driver.h>
|
||||
#include <nel/3d/u_cloud_scape.h>
|
||||
|
||||
#include "game_share/scenario_entry_points.h"
|
||||
|
||||
#include "client_cfg.h"
|
||||
#include "misc.h"
|
||||
#include "global.h"
|
||||
#include "world_database_manager.h"
|
||||
#include "continent_manager.h"
|
||||
#include "user_entity.h"
|
||||
#include "view.h"
|
||||
#include "ig_client.h"
|
||||
#include "entities.h"
|
||||
#include "input.h"
|
||||
#include "sound_manager.h"
|
||||
#include "camera.h"
|
||||
|
||||
using namespace NLMISC;
|
||||
using namespace NL3D;
|
||||
|
||||
//---------------------------------------------------
|
||||
// Compare ClientCfg and LastClientCfg to know what we must update
|
||||
//---------------------------------------------------
|
||||
void updateFromClientCfg()
|
||||
{
|
||||
CClientConfig::setValues();
|
||||
ClientCfg.IsInvalidated = false;
|
||||
|
||||
// GRAPHICS - GENERAL
|
||||
//---------------------------------------------------
|
||||
if ((ClientCfg.Windowed != LastClientCfg.Windowed) ||
|
||||
(ClientCfg.Width != LastClientCfg.Width) ||
|
||||
(ClientCfg.Height != LastClientCfg.Height) ||
|
||||
(ClientCfg.Depth != LastClientCfg.Depth) ||
|
||||
(ClientCfg.Frequency != LastClientCfg.Frequency))
|
||||
{
|
||||
setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth,
|
||||
ClientCfg.Windowed, ClientCfg.Frequency));
|
||||
}
|
||||
|
||||
if (ClientCfg.DivideTextureSizeBy2 != LastClientCfg.DivideTextureSizeBy2)
|
||||
{
|
||||
if (ClientCfg.DivideTextureSizeBy2)
|
||||
Driver->forceTextureResize(2);
|
||||
else
|
||||
Driver->forceTextureResize(1);
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.WaitVBL != LastClientCfg.WaitVBL)
|
||||
{
|
||||
if(ClientCfg.WaitVBL)
|
||||
Driver->setSwapVBLInterval(1);
|
||||
else
|
||||
Driver->setSwapVBLInterval(0);
|
||||
}
|
||||
|
||||
// GRAPHICS - LANDSCAPE
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.LandscapeThreshold != LastClientCfg.LandscapeThreshold)
|
||||
{
|
||||
if (Landscape) Landscape->setThreshold(ClientCfg.getActualLandscapeThreshold());
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.LandscapeTileNear != LastClientCfg.LandscapeTileNear)
|
||||
{
|
||||
if (Landscape) Landscape->setTileNear(ClientCfg.LandscapeTileNear);
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
if (Landscape)
|
||||
{
|
||||
if (ClientCfg.Vision != LastClientCfg.Vision)
|
||||
{
|
||||
if (!ClientCfg.Light)
|
||||
{
|
||||
// Not in an indoor ?
|
||||
if (ContinentMngr.cur() && !ContinentMngr.cur()->Indoor)
|
||||
{
|
||||
// Refresh All Zone in streaming according to the refine position
|
||||
std::vector<string> zonesAdded;
|
||||
std::vector<string> zonesRemoved;
|
||||
const R2::CScenarioEntryPoints::CCompleteIsland *ci = R2::CScenarioEntryPoints::getInstance().getCompleteIslandFromCoords(CVector2f((float) UserEntity->pos().x, (float) UserEntity->pos().y));
|
||||
Landscape->refreshAllZonesAround(View.refinePos(), ClientCfg.Vision + ExtraZoneLoadingVision, zonesAdded, zonesRemoved, ProgressBar, ci ? &(ci->ZoneIDs) : NULL);
|
||||
LandscapeIGManager.unloadArrayZoneIG(zonesRemoved);
|
||||
LandscapeIGManager.loadArrayZoneIG(zonesAdded);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.Vision != LastClientCfg.Vision || ClientCfg.FoV!=LastClientCfg.FoV ||
|
||||
ClientCfg.Windowed != LastClientCfg.Windowed || ClientCfg.ScreenAspectRatio != LastClientCfg.ScreenAspectRatio )
|
||||
{
|
||||
updateCameraPerspective();
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
if (Landscape)
|
||||
{
|
||||
if (ClientCfg.MicroVeget != LastClientCfg.MicroVeget)
|
||||
{
|
||||
if(ClientCfg.MicroVeget)
|
||||
{
|
||||
// if configured, enable the vegetable and load the texture.
|
||||
Landscape->enableVegetable(true);
|
||||
// Default setup. TODO later by gameDev.
|
||||
Landscape->setVegetableWind(CVector(0.5, 0.5, 0).normed(), 0.5, 1, 0);
|
||||
// Default setup. should work well for night/day transition in 30 minutes.
|
||||
// Because all vegetables will be updated every 20 seconds => 90 steps.
|
||||
Landscape->setVegetableUpdateLightingFrequency(1/20.f);
|
||||
// Density (percentage to ratio)
|
||||
Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Landscape->enableVegetable(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.MicroVegetDensity != LastClientCfg.MicroVegetDensity)
|
||||
{
|
||||
// Density (percentage to ratio)
|
||||
if (Landscape) Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f);
|
||||
}
|
||||
|
||||
// GRAPHICS - SPECIAL EFFECTS
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.FxNbMaxPoly != LastClientCfg.FxNbMaxPoly)
|
||||
{
|
||||
if (Scene->getGroupLoadMaxPolygon("Fx") != ClientCfg.FxNbMaxPoly)
|
||||
Scene->setGroupLoadMaxPolygon("Fx", ClientCfg.FxNbMaxPoly);
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.Cloud != LastClientCfg.Cloud)
|
||||
{
|
||||
if (ClientCfg.Cloud)
|
||||
{
|
||||
InitCloudScape = true;
|
||||
CloudScape = Scene->createCloudScape();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CloudScape != NULL)
|
||||
Scene->deleteCloudScape(CloudScape);
|
||||
CloudScape = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.CloudQuality != LastClientCfg.CloudQuality)
|
||||
{
|
||||
if (CloudScape != NULL)
|
||||
CloudScape->setQuality(ClientCfg.CloudQuality);
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.CloudUpdate != LastClientCfg.CloudUpdate)
|
||||
{
|
||||
if (CloudScape != NULL)
|
||||
CloudScape->setNbCloudToUpdateIn80ms(ClientCfg.CloudUpdate);
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.Shadows != LastClientCfg.Shadows)
|
||||
{
|
||||
// Enable/Disable Receive on Landscape
|
||||
if(Landscape)
|
||||
{
|
||||
Landscape->enableReceiveShadowMap(ClientCfg.Shadows);
|
||||
}
|
||||
// Enable/Disable Cast for all entities
|
||||
for(uint i=0;i<EntitiesMngr.entities().size();i++)
|
||||
{
|
||||
CEntityCL *ent= EntitiesMngr.entities()[i];
|
||||
if(ent)
|
||||
ent->updateCastShadowMap();
|
||||
}
|
||||
}
|
||||
|
||||
// GRAPHICS - CHARACTERS
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.SkinNbMaxPoly != LastClientCfg.SkinNbMaxPoly)
|
||||
{
|
||||
if (Scene->getGroupLoadMaxPolygon("Skin") != ClientCfg.SkinNbMaxPoly)
|
||||
Scene->setGroupLoadMaxPolygon("Skin", ClientCfg.SkinNbMaxPoly);
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.NbMaxSkeletonNotCLod != LastClientCfg.NbMaxSkeletonNotCLod )
|
||||
{
|
||||
Scene->setMaxSkeletonsInNotCLodForm(ClientCfg.NbMaxSkeletonNotCLod);
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.CharacterFarClip != LastClientCfg.CharacterFarClip)
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.HDEntityTexture != LastClientCfg.HDEntityTexture)
|
||||
{
|
||||
// Don't reload Texture, will be done at next Game Start
|
||||
}
|
||||
|
||||
// INTERFACE works
|
||||
|
||||
|
||||
// INPUTS
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.CursorSpeed != LastClientCfg.CursorSpeed)
|
||||
SetMouseSpeed (ClientCfg.CursorSpeed);
|
||||
|
||||
if (ClientCfg.CursorAcceleration != LastClientCfg.CursorAcceleration)
|
||||
SetMouseAcceleration (ClientCfg.CursorAcceleration);
|
||||
|
||||
if (ClientCfg.HardwareCursor != LastClientCfg.HardwareCursor)
|
||||
{
|
||||
if (ClientCfg.HardwareCursor != IsMouseCursorHardware())
|
||||
{
|
||||
InitMouseWithCursor (ClientCfg.HardwareCursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// SOUND
|
||||
//---------------------------------------------------
|
||||
bool mustReloadSoundMngrContinent= false;
|
||||
|
||||
// disable/enable sound?
|
||||
if (ClientCfg.SoundOn != LastClientCfg.SoundOn)
|
||||
{
|
||||
if (SoundMngr && !ClientCfg.SoundOn)
|
||||
{
|
||||
nlwarning("Deleting sound manager...");
|
||||
delete SoundMngr;
|
||||
SoundMngr = NULL;
|
||||
}
|
||||
else if (SoundMngr == NULL && ClientCfg.SoundOn)
|
||||
{
|
||||
nlwarning("Creating sound manager...");
|
||||
SoundMngr = new CSoundManager();
|
||||
try
|
||||
{
|
||||
SoundMngr->init(NULL);
|
||||
}
|
||||
catch(const Exception &e)
|
||||
{
|
||||
nlwarning("init : Error when creating 'SoundMngr' : %s", e.what());
|
||||
SoundMngr = 0;
|
||||
}
|
||||
|
||||
// re-init with good SFX/Music Volume
|
||||
if(SoundMngr)
|
||||
{
|
||||
SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume);
|
||||
SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nlwarning("Sound config error !");
|
||||
}
|
||||
|
||||
mustReloadSoundMngrContinent= true;
|
||||
}
|
||||
|
||||
// change EAX?
|
||||
if ( SoundMngr && LastClientCfg.SoundOn &&
|
||||
(ClientCfg.UseEax != LastClientCfg.UseEax) )
|
||||
{
|
||||
SoundMngr->reset();
|
||||
|
||||
mustReloadSoundMngrContinent= true;
|
||||
}
|
||||
|
||||
// change SoundForceSoftwareBuffer?
|
||||
if ( SoundMngr && LastClientCfg.SoundOn &&
|
||||
(ClientCfg.SoundForceSoftwareBuffer != LastClientCfg.SoundForceSoftwareBuffer) )
|
||||
{
|
||||
SoundMngr->reset();
|
||||
|
||||
mustReloadSoundMngrContinent= true;
|
||||
}
|
||||
|
||||
// change MaxTrack? don't reset
|
||||
if ( SoundMngr && LastClientCfg.SoundOn &&
|
||||
(ClientCfg.MaxTrack != LastClientCfg.MaxTrack))
|
||||
{
|
||||
SoundMngr->getMixer()->changeMaxTrack(ClientCfg.MaxTrack);
|
||||
}
|
||||
|
||||
// change SoundFX Volume? don't reset
|
||||
if (SoundMngr && ClientCfg.SoundSFXVolume != LastClientCfg.SoundSFXVolume)
|
||||
{
|
||||
SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume);
|
||||
}
|
||||
|
||||
// change Game Music Volume? don't reset
|
||||
if (SoundMngr && ClientCfg.SoundGameMusicVolume != LastClientCfg.SoundGameMusicVolume)
|
||||
{
|
||||
SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume);
|
||||
}
|
||||
|
||||
// reload only if active and reseted
|
||||
if (mustReloadSoundMngrContinent && SoundMngr && ContinentMngr.cur() && !ContinentMngr.cur()->Indoor && UserEntity)
|
||||
{
|
||||
SoundMngr->loadContinent(ContinentMngr.getCurrentContinentSelectName(), UserEntity->pos());
|
||||
}
|
||||
|
||||
// Ok backup the new clientcfg
|
||||
LastClientCfg = ClientCfg;
|
||||
}
|
||||
|
||||
/* end of file */
|
32
code/ryzom/client/src/main_loop_utilities.h
Normal file
32
code/ryzom/client/src/main_loop_utilities.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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 CL_MAIN_LOOP_UTILITIES_H
|
||||
#define CL_MAIN_LOOP_UTILITIES_H
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// Update Utilities (configuration etc)
|
||||
// Only put utility update functions here that are used in the main loop.
|
||||
// This is mainly for system configuration related functions
|
||||
// such as config file changes.
|
||||
|
||||
/// Compare ClientCfg and LastClientCfg to know what we must update
|
||||
void updateFromClientCfg();
|
||||
|
||||
#endif // CL_MAIN_LOOP_UTILITIES_H
|
||||
|
||||
/* end of file */
|
74
code/ryzom/client/src/ping.cpp
Normal file
74
code/ryzom/client/src/ping.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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/misc/types_nl.h>
|
||||
#include "ping.h"
|
||||
|
||||
#include "interface_v3/interface_manager.h"
|
||||
#include "time_client.h"
|
||||
|
||||
using namespace NLMISC;
|
||||
using namespace NLGUI;
|
||||
|
||||
void CPing::init()
|
||||
{
|
||||
CInterfaceManager *pIM = CInterfaceManager::getInstance();
|
||||
if(pIM)
|
||||
{
|
||||
CCDBNodeLeaf *pNodeLeaf = CDBManager::getInstance()->getDbProp("SERVER:DEBUG_INFO:Ping", false);
|
||||
if(pNodeLeaf)
|
||||
{
|
||||
ICDBNode::CTextId textId;
|
||||
pNodeLeaf->addObserver(this, textId);
|
||||
// nlwarning("CPing: cannot add the observer");
|
||||
}
|
||||
else
|
||||
nlwarning("CPing: 'SERVER:DEBUG_INFO:Ping' does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
void CPing::release()
|
||||
{
|
||||
CInterfaceManager *pIM = CInterfaceManager::getInstance();
|
||||
if(pIM)
|
||||
{
|
||||
CCDBNodeLeaf *pNodeLeaf = CDBManager::getInstance()->getDbProp("SERVER:DEBUG_INFO:Ping", false);
|
||||
if(pNodeLeaf)
|
||||
{
|
||||
ICDBNode::CTextId textId;
|
||||
pNodeLeaf->removeObserver(this, textId);
|
||||
}
|
||||
else
|
||||
nlwarning("CPing: 'SERVER:DEBUG_INFO:Ping' does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
void CPing::update(NLMISC::ICDBNode* node)
|
||||
{
|
||||
CCDBNodeLeaf *leaf = safe_cast<CCDBNodeLeaf *>(node);
|
||||
uint32 before = (uint32)leaf->getValue32();
|
||||
uint32 current = (uint32)(0xFFFFFFFF & ryzomGetLocalTime());
|
||||
if(before > current)
|
||||
{
|
||||
//nlwarning("DB PING Pb before '%u' after '%u'.", before, current);
|
||||
if(ClientCfg.Check)
|
||||
nlstop;
|
||||
}
|
||||
_Ping = current - before;
|
||||
_RdyToPing = true;
|
||||
}
|
||||
|
||||
/* end of file */
|
62
code/ryzom/client/src/ping.h
Normal file
62
code/ryzom/client/src/ping.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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 CL_PING_H
|
||||
#define CL_PING_H
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include <nel/misc/cdb.h>
|
||||
|
||||
///////////
|
||||
// CLASS //
|
||||
///////////
|
||||
/**
|
||||
* Class to manage the ping computed with the database.
|
||||
* \author Guillaume PUZIN
|
||||
* \author Nevrax France
|
||||
* \date 2003
|
||||
*/
|
||||
class CPing : public NLMISC::ICDBNode::IPropertyObserver
|
||||
{
|
||||
private:
|
||||
uint32 _Ping;
|
||||
bool _RdyToPing;
|
||||
|
||||
public:
|
||||
// Constructor.
|
||||
CPing() {_Ping = 0; _RdyToPing = true;}
|
||||
// Destructor.
|
||||
~CPing() {;}
|
||||
|
||||
// Add an observer on the database for the ping.
|
||||
void init();
|
||||
|
||||
// Release the observer on the database for the ping.
|
||||
void release();
|
||||
|
||||
// Method called when the ping message is back.
|
||||
virtual void update(NLMISC::ICDBNode* node);
|
||||
|
||||
// return the ping in ms.
|
||||
uint32 getValue() {return _Ping;}
|
||||
|
||||
void rdyToPing(bool rdy) {_RdyToPing = rdy;}
|
||||
bool rdyToPing() const {return _RdyToPing;}
|
||||
};
|
||||
|
||||
#endif // CL_PING_H
|
||||
|
||||
/* end of file */
|
160
code/ryzom/client/src/profiling.cpp
Normal file
160
code/ryzom/client/src/profiling.cpp
Normal file
|
@ -0,0 +1,160 @@
|
|||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// 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/misc/types_nl.h>
|
||||
#include "profiling.h"
|
||||
|
||||
// NeL includes
|
||||
#include <nel/3d/u_driver.h>
|
||||
|
||||
// Project includes
|
||||
#include "misc.h"
|
||||
#include "sound_manager.h"
|
||||
|
||||
///////////
|
||||
// USING //
|
||||
///////////
|
||||
using namespace NLMISC;
|
||||
using namespace NL3D;
|
||||
|
||||
////////////
|
||||
// EXTERN //
|
||||
////////////
|
||||
extern UDriver *Driver;
|
||||
|
||||
/////////////
|
||||
// GLOBALS //
|
||||
/////////////
|
||||
bool Profiling = false; // Are we in Profile mode?
|
||||
uint ProfileNumFrame = 0;
|
||||
bool WantProfiling = false;
|
||||
bool ProfilingVBLock = false;
|
||||
bool WantProfilingVBLock = false;
|
||||
|
||||
// ********************************************************************
|
||||
|
||||
/// Test Profiling and run?
|
||||
void testLaunchProfile()
|
||||
{
|
||||
if(!WantProfiling)
|
||||
return;
|
||||
|
||||
// comes from ActionHandler
|
||||
WantProfiling= false;
|
||||
|
||||
#ifdef _PROFILE_ON_
|
||||
if( !Profiling )
|
||||
{
|
||||
// start the bench.
|
||||
NLMISC::CHTimer::startBench();
|
||||
ProfileNumFrame = 0;
|
||||
Driver->startBench();
|
||||
if (SoundMngr)
|
||||
SoundMngr->getMixer()->startDriverBench();
|
||||
// state
|
||||
Profiling= true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// end the bench.
|
||||
if (SoundMngr)
|
||||
SoundMngr->getMixer()->endDriverBench();
|
||||
NLMISC::CHTimer::endBench();
|
||||
Driver->endBench();
|
||||
|
||||
|
||||
// Display and save profile to a File.
|
||||
CLog log;
|
||||
CFileDisplayer fileDisplayer(NLMISC::CFile::findNewFile(getLogDirectory() + "profile.log"));
|
||||
CStdDisplayer stdDisplayer;
|
||||
log.addDisplayer(&fileDisplayer);
|
||||
log.addDisplayer(&stdDisplayer);
|
||||
// diplay
|
||||
NLMISC::CHTimer::displayHierarchicalByExecutionPathSorted(&log, CHTimer::TotalTime, true, 48, 2);
|
||||
NLMISC::CHTimer::displayHierarchical(&log, true, 48, 2);
|
||||
NLMISC::CHTimer::displayByExecutionPath(&log, CHTimer::TotalTime);
|
||||
NLMISC::CHTimer::display(&log, CHTimer::TotalTime);
|
||||
NLMISC::CHTimer::display(&log, CHTimer::TotalTimeWithoutSons);
|
||||
Driver->displayBench(&log);
|
||||
|
||||
if (SoundMngr)
|
||||
SoundMngr->getMixer()->displayDriverBench(&log);
|
||||
|
||||
// state
|
||||
Profiling= false;
|
||||
}
|
||||
#endif // #ifdef _PROFILE_ON_
|
||||
}
|
||||
|
||||
// ********************************************************************
|
||||
|
||||
/// Test ProfilingVBLock and run?
|
||||
void testLaunchProfileVBLock()
|
||||
{
|
||||
// If running, must stop for this frame.
|
||||
if(ProfilingVBLock)
|
||||
{
|
||||
std::vector<string> strs;
|
||||
Driver->endProfileVBHardLock(strs);
|
||||
nlinfo("Profile VBLock");
|
||||
nlinfo("**************");
|
||||
for(uint i=0;i<strs.size();i++)
|
||||
{
|
||||
nlinfo(strs[i].c_str());
|
||||
}
|
||||
ProfilingVBLock= false;
|
||||
|
||||
// Display additional info on allocated VBHards
|
||||
nlinfo("VBHard list");
|
||||
nlinfo("**************");
|
||||
Driver->profileVBHardAllocation(strs);
|
||||
for(uint i=0;i<strs.size();i++)
|
||||
{
|
||||
nlinfo(strs[i].c_str());
|
||||
}
|
||||
strs.clear();
|
||||
Driver->endProfileIBLock(strs);
|
||||
nlinfo("Profile Index Buffer Lock");
|
||||
nlinfo("**************");
|
||||
for(uint i=0;i<strs.size();i++)
|
||||
{
|
||||
nlinfo(strs[i].c_str());
|
||||
}
|
||||
ProfilingVBLock= false;
|
||||
|
||||
// Display additional info on allocated VBHards
|
||||
/*
|
||||
nlinfo("Index Buffer list");
|
||||
nlinfo("**************");
|
||||
Driver->profileIBAllocation(strs);
|
||||
for(uint i=0;i<strs.size();i++)
|
||||
{
|
||||
nlinfo(strs[i].c_str());
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// comes from ActionHandler
|
||||
if(WantProfilingVBLock)
|
||||
{
|
||||
WantProfilingVBLock= false;
|
||||
ProfilingVBLock= true;
|
||||
Driver->startProfileVBHardLock();
|
||||
Driver->startProfileIBLock();
|
||||
}
|
||||
}
|
||||
|
||||
/* end of file */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue