Merge with default

This commit is contained in:
kaetemi 2013-09-07 16:25:45 +02:00
commit beb66b19b7
95 changed files with 9415 additions and 5002 deletions

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

View file

@ -58,6 +58,8 @@ ELSE(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES)
SET(MYSQL_LIBRARIES optimized ${MYSQL_LIBRARY_RELEASE}) SET(MYSQL_LIBRARIES optimized ${MYSQL_LIBRARY_RELEASE})
IF(MYSQL_LIBRARY_DEBUG) IF(MYSQL_LIBRARY_DEBUG)
SET(MYSQL_LIBRARIES ${MYSQL_LIBRARIES} debug ${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) ENDIF(MYSQL_LIBRARY_DEBUG)
FIND_PACKAGE(OpenSSL) FIND_PACKAGE(OpenSSL)
IF(OPENSSL_FOUND) IF(OPENSSL_FOUND)

View file

@ -320,6 +320,8 @@ MACRO(NL_SETUP_NEL_DEFAULT_OPTIONS)
OPTION(WITH_NEL_MAXPLUGIN "Build NeL 3dsMax Plugin" OFF) OPTION(WITH_NEL_MAXPLUGIN "Build NeL 3dsMax Plugin" OFF)
OPTION(WITH_NEL_SAMPLES "Build NeL Samples" ON ) OPTION(WITH_NEL_SAMPLES "Build NeL Samples" ON )
OPTION(WITH_NEL_TESTS "Build NeL Unit Tests" ON ) OPTION(WITH_NEL_TESTS "Build NeL Unit Tests" ON )
OPTION(WITH_LIBOVR "With LibOVR support" OFF)
ENDMACRO(NL_SETUP_NEL_DEFAULT_OPTIONS) ENDMACRO(NL_SETUP_NEL_DEFAULT_OPTIONS)
MACRO(NL_SETUP_NELNS_DEFAULT_OPTIONS) MACRO(NL_SETUP_NELNS_DEFAULT_OPTIONS)

View file

@ -41,6 +41,10 @@ IF(WITH_GTK)
FIND_PACKAGE(GTK2) FIND_PACKAGE(GTK2)
ENDIF(WITH_GTK) ENDIF(WITH_GTK)
IF(WITH_LIBOVR)
FIND_PACKAGE(LibOVR)
ENDIF(WITH_LIBOVR)
IF(WITH_INSTALL_LIBRARIES) IF(WITH_INSTALL_LIBRARIES)
IF(UNIX) IF(UNIX)
SET(prefix ${CMAKE_INSTALL_PREFIX}) SET(prefix ${CMAKE_INSTALL_PREFIX})

View file

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

View file

@ -30,6 +30,7 @@
#include "nel/3d/vertex_buffer.h" #include "nel/3d/vertex_buffer.h"
#include "nel/3d/index_buffer.h" #include "nel/3d/index_buffer.h"
#include "nel/3d/vertex_program.h" #include "nel/3d/vertex_program.h"
#include "nel/3d/pixel_program.h"
#include "nel/3d/material.h" #include "nel/3d/material.h"
#include "nel/misc/mutex.h" #include "nel/misc/mutex.h"
#include "nel/3d/primitive_profile.h" #include "nel/3d/primitive_profile.h"
@ -141,7 +142,6 @@ public:
*/ */
enum TMatrixCount { MaxModelMatrix= 16 }; enum TMatrixCount { MaxModelMatrix= 16 };
protected: protected:
CSynchronized<TTexDrvInfoPtrMap> _SyncTexDrvInfos; CSynchronized<TTexDrvInfoPtrMap> _SyncTexDrvInfos;
@ -152,6 +152,7 @@ protected:
TIBDrvInfoPtrList _IBDrvInfos; TIBDrvInfoPtrList _IBDrvInfos;
TPolygonMode _PolygonMode; TPolygonMode _PolygonMode;
TVtxPrgDrvInfoPtrList _VtxPrgDrvInfos; TVtxPrgDrvInfoPtrList _VtxPrgDrvInfos;
TPixelPrgDrvInfoPtrList _PixelPrgDrvInfos;
TShaderDrvInfoPtrList _ShaderDrvInfos; TShaderDrvInfoPtrList _ShaderDrvInfos;
uint _ResetCounter; uint _ResetCounter;
@ -172,6 +173,7 @@ public:
*/ */
// @{ // @{
virtual void disableHardwareVertexProgram()=0; virtual void disableHardwareVertexProgram()=0;
virtual void disableHardwarePixelProgram()=0;
virtual void disableHardwareVertexArrayAGP()=0; virtual void disableHardwareVertexArrayAGP()=0;
virtual void disableHardwareTextureShader()=0; virtual void disableHardwareTextureShader()=0;
// @} // @}
@ -857,6 +859,8 @@ public:
uint32 cubeFace = 0 uint32 cubeFace = 0
) = 0 ; ) = 0 ;
virtual ITexture *getRenderTarget() const = 0;
/** Trick method : copy the current texture target into another texture without updating the current texture. /** Trick method : copy the current texture target into another texture without updating the current texture.
* *
* This method copies the current texture into another texture. * This method copies the current texture into another texture.
@ -1002,13 +1006,19 @@ public:
/** /**
* Does the driver supports vertex programs ? * Does the driver supports vertex programs ?
*/ */
virtual bool isVertexProgramSupported () const =0; virtual bool supportVertexProgram () const =0;
/** /**
* Does the driver supports vertex program, but emulated by CPU ? * Does the driver supports vertex program, but emulated by CPU ?
*/ */
virtual bool isVertexProgramEmulated () const =0; virtual bool isVertexProgramEmulated () const =0;
/**
* Does the driver supports pixel programs ?
*/
virtual bool supportPixelProgram() const =0;
virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const =0;
/** /**
@ -1021,7 +1031,16 @@ public:
virtual bool activeVertexProgram (CVertexProgram *program) =0; virtual bool activeVertexProgram (CVertexProgram *program) =0;
/** /**
* Setup constant values. * Activate / disactivate a pixel program
*
* \param program is a pointer on a pixel program. Can be NULL to disable the current pixel program.
*
* \return true if setup/unsetup successed, false else.
*/
virtual bool activePixelProgram (CPixelProgram *program) =0;
/**
* Setup vertex program constant (uniform) values.
*/ */
virtual void setConstant (uint index, float, float, float, float) =0; virtual void setConstant (uint index, float, float, float, float) =0;
virtual void setConstant (uint index, double, double, double, double) =0; virtual void setConstant (uint index, double, double, double, double) =0;
@ -1031,7 +1050,34 @@ public:
virtual void setConstant (uint index, uint num, const float *src) =0; virtual void setConstant (uint index, uint num, const float *src) =0;
/// setup several 4 double csts taken from the given tab /// setup several 4 double csts taken from the given tab
virtual void setConstant (uint index, uint num, const double *src) =0; virtual void setConstant (uint index, uint num, const double *src) =0;
// TODO: rename to setVertexProgramConstant
/**
* Setup pixel program constant (uniform) values.
*/
virtual void setPixelProgramConstant (uint index, float, float, float, float) =0;
virtual void setPixelProgramConstant (uint index, double, double, double, double) =0;
virtual void setPixelProgramConstant (uint index, const NLMISC::CVector& value) =0;
virtual void setPixelProgramConstant (uint index, const NLMISC::CVectorD& value) =0;
/// setup several 4 float csts taken from the given tab
virtual void setPixelProgramConstant (uint index, uint num, const float *src) =0;
/// setup several 4 double csts taken from the given tab
virtual void setPixelProgramConstant (uint index, uint num, const double *src) =0;
// TODO: uint32 and sint32 uniform types supported in opengl from gp4fp and gp5fp and sint32 in d3d
/**
* Setup constants with a current matrix.
*
* This call must be done after setFrustum(), setupViewMatrix() or setupModelMatrix() to get correct
* results.
*
* \param index is the base constant index where to store the matrix. This index must be a multiple of 4.
* \param matrix is the matrix id to store in the constants
* \param transform is the transformation to apply to the matrix before store it in the constants.
*
*/
virtual void setPixelProgramConstantMatrix (uint index, TMatrix matrix, TTransform transform) =0;
/** /**
* Setup constants with a current matrix. * Setup constants with a current matrix.
* *
@ -1080,10 +1126,10 @@ public:
/// test whether the device supports some form of texture shader. (could be limited to DX6 EMBM for example) /// test whether the device supports some form of texture shader. (could be limited to DX6 EMBM for example)
virtual bool supportTextureShaders() const = 0; virtual bool supportTextureShaders() const = 0;
// Is the shader water supported ? If not, the driver caller should implement its own version // Is the shader water supported ? If not, the driver caller should implement its own version
virtual bool isWaterShaderSupported() const = 0; virtual bool supportWaterShader() const = 0;
// //
/// test whether a texture addressing mode is supported /// test whether a texture addressing mode is supported
virtual bool isTextureAddrModeSupported(CMaterial::TTexAddressingMode mode) const = 0; virtual bool supportTextureAddrMode(CMaterial::TTexAddressingMode mode) const = 0;
/** setup the 2D matrix for the OffsetTexture, OffsetTextureScale and OffsetTexture addressing mode /** setup the 2D matrix for the OffsetTexture, OffsetTextureScale and OffsetTexture addressing mode
* It should be stored as the following * It should be stored as the following
* [a0 a1] * [a0 a1]
@ -1258,6 +1304,7 @@ protected:
friend class ITextureDrvInfos; friend class ITextureDrvInfos;
friend class IMaterialDrvInfos; friend class IMaterialDrvInfos;
friend class IVertexProgramDrvInfos; friend class IVertexProgramDrvInfos;
friend class IPixelProgramDrvInfos;
friend class IShaderDrvInfos; friend class IShaderDrvInfos;
/// remove ptr from the lists in the driver. /// remove ptr from the lists in the driver.
@ -1268,6 +1315,7 @@ protected:
void removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt); void removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt);
void removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt); void removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt);
void removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt); void removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt);
void removePixelPrgDrvInfoPtr(ItPixelPrgDrvInfoPtrList pixelPrgDrvInfoIt);
private: private:
bool _StaticMemoryToVRAM; bool _StaticMemoryToVRAM;

View file

@ -133,6 +133,7 @@ public:
// @{ // @{
virtual void disableHardwareVertexProgram(); virtual void disableHardwareVertexProgram();
virtual void disableHardwarePixelProgram();
virtual void disableHardwareVertexArrayAGP(); virtual void disableHardwareVertexArrayAGP();
virtual void disableHardwareTextureShader(); virtual void disableHardwareTextureShader();

View file

@ -171,7 +171,12 @@ public:
* - Alpha of texture in stage 0 is blended with alpha of texture in stage 1. Blend done with the alpha color of each * - 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 * stage and the whole is multiplied by the alpha in color vertex [AT0*ADiffuseCol+AT1*(1-ADiffuseCol)]*AStage
* - RGB still unchanged * - RGB still unchanged
* * Water :
* - Water
* PostProcessing :
* - For internal use only when a pixel program is set manually through activePixelProgram.
* - Only textures are set by CMaterial (does not work with ps_3_0 for some reason), the rest must be set manually.
* - May be replaced in the future by some generic shader system.
*/ */
enum TShader { Normal=0, enum TShader { Normal=0,
Bump, Bump,
@ -183,6 +188,7 @@ public:
PerPixelLightingNoSpec, PerPixelLightingNoSpec,
Cloud, Cloud,
Water, Water,
PostProcessing,
shaderCount}; shaderCount};
/// \name Texture Env Modes. /// \name Texture Env Modes.

View file

@ -0,0 +1,111 @@
/** \file pixel_program.h
* Pixel program definition
*
* $Id: pixel_program.h,v 1.1.2.3 2007/07/06 15:58:45 legallo Exp $
*/
/* 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 <list>
namespace NL3D {
// List typedef.
class IDriver;
class IPixelProgramDrvInfos;
typedef std::list<IPixelProgramDrvInfos*> TPixelPrgDrvInfoPtrList;
typedef TPixelPrgDrvInfoPtrList::iterator ItPixelPrgDrvInfoPtrList;
// Class for interaction of pixel program with Driver.
// IPixelProgramDrvInfos represent the real data of the pixel program, stored into the driver.
class IPixelProgramDrvInfos : public NLMISC::CRefCount
{
private:
IDriver *_Driver;
ItPixelPrgDrvInfoPtrList _DriverIterator;
public:
IPixelProgramDrvInfos (IDriver *drv, ItPixelPrgDrvInfoPtrList it);
// The virtual dtor is important.
virtual ~IPixelProgramDrvInfos(void);
};
//-------------------------------------------------------------------------------
class CPixelProgram : public NLMISC::CRefCount
{
public:
enum TProfile
{
// TODO:
// If it's more useful, change this to a flags bitfield and
// change the d3d (and gl) code to generate the bitfield of
// supported modes instead of doing a >= version check.
// direct3d - 0xD3D0,major,minor
ps_1_1 = 0xD3D00101,
ps_1_2 = 0xD3D00102,
ps_1_3 = 0xD3D00103,
ps_1_4 = 0xD3D00104,
ps_2_0 = 0xD3D00200,
ps_2_x = 0xD3D00201, // not sure...
ps_3_0 = 0xD3D00300,
// opengl - 0x0610,bitfield
// fp20 = 0x061B0001, // very limited and outdated, unnecessary
// fp30 = 0x06100002, // NV_fragment_program, now arbfp1, redundant
arbfp1 = 0x06100004, // ARB_fragment_program
fp40 = 0x06100008, // NV_fragment_program2, arbfp1 with "OPTION NV_fragment_program2;\n"
gp4fp = 0x06100010, // NV_gpu_program4
gp5fp = 0x06100020, // NV_gpu_program5
};
/// Constructor
CPixelProgram (const char* program);
/// Destructor
virtual ~CPixelProgram ();
/// Get the program
inline const std::string& getProgram() const { return _Program; };
/// The driver informations. For the driver implementation only.
NLMISC::CRefPtr<IPixelProgramDrvInfos> _DrvInfo;
protected:
/// The progam
std::string _Program;
};
} // NL3D
#endif // NL_PIXEL_PROGRAM_H
/* End of vertex_program.h */

View file

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

View 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 */

View 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 */

View 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 */

View 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 CPixelProgram;
#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;
CPixelProgram *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 */

View file

@ -168,6 +168,7 @@ public:
*/ */
// @{ // @{
virtual void disableHardwareVertexProgram()=0; virtual void disableHardwareVertexProgram()=0;
virtual void disableHardwarePixelProgram()=0;
virtual void disableHardwareVertexArrayAGP()=0; virtual void disableHardwareVertexArrayAGP()=0;
virtual void disableHardwareTextureShader()=0; virtual void disableHardwareTextureShader()=0;
// @} // @}

View file

@ -164,7 +164,9 @@ SOURCE_GROUP(Driver FILES
vertex_program.cpp vertex_program.cpp
../../include/nel/3d/vertex_program.h ../../include/nel/3d/vertex_program.h
vertex_program_parse.cpp 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)
SOURCE_GROUP(Font FILES SOURCE_GROUP(Font FILES
computed_string.cpp computed_string.cpp
@ -686,12 +688,22 @@ SOURCE_GROUP(Shadows FILES
../../include/nel/3d/shadow_map_manager.h ../../include/nel/3d/shadow_map_manager.h
shadow_poly_receiver.cpp shadow_poly_receiver.cpp
../../include/nel/3d/shadow_poly_receiver.h) ../../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_debugger.cpp
../../include/nel/3d/stereo_debugger.h)
NL_TARGET_LIB(nel3d ${HEADERS} ${SRC}) 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})
TARGET_LINK_LIBRARIES(nel3d nelmisc ${FREETYPE_LIBRARY}) TARGET_LINK_LIBRARIES(nel3d nelmisc ${FREETYPE_LIBRARY} ${LIBOVR_LIBRARIES})
SET_TARGET_PROPERTIES(nel3d PROPERTIES LINK_INTERFACE_LIBRARIES "") SET_TARGET_PROPERTIES(nel3d PROPERTIES LINK_INTERFACE_LIBRARIES "")
NL_DEFAULT_PROPS(nel3d "NeL, Library: NeL 3D") NL_DEFAULT_PROPS(nel3d "NeL, Library: NeL 3D")
NL_ADD_RUNTIME_FLAGS(nel3d) NL_ADD_RUNTIME_FLAGS(nel3d)
@ -701,6 +713,8 @@ NL_ADD_LIB_SUFFIX(nel3d)
ADD_DEFINITIONS(${LIBXML2_DEFINITIONS}) ADD_DEFINITIONS(${LIBXML2_DEFINITIONS})
ADD_DEFINITIONS(${LIBOVR_DEFINITIONS})
IF(WITH_PCH) IF(WITH_PCH)
ADD_NATIVE_PRECOMPILED_HEADER(nel3d ${CMAKE_CURRENT_SOURCE_DIR}/std3d.h ${CMAKE_CURRENT_SOURCE_DIR}/std3d.cpp) ADD_NATIVE_PRECOMPILED_HEADER(nel3d ${CMAKE_CURRENT_SOURCE_DIR}/std3d.h ${CMAKE_CURRENT_SOURCE_DIR}/std3d.cpp)
ENDIF(WITH_PCH) ENDIF(WITH_PCH)

View file

@ -285,6 +285,8 @@ void CBloomEffect::initBloom() // clientcfg
if(!_Init) if(!_Init)
init(); init();
_OriginalRenderTarget = static_cast<CDriverUser *>(_Driver)->getDriver()->getRenderTarget();
// if window resize, reinitialize textures // if window resize, reinitialize textures
if(_WndWidth!=_Driver->getWindowWidth() || _WndHeight!=_Driver->getWindowHeight()) if(_WndWidth!=_Driver->getWindowWidth() || _WndHeight!=_Driver->getWindowHeight())
{ {
@ -349,13 +351,15 @@ void CBloomEffect::initBloom() // clientcfg
} }
} }
NL3D::CTextureUser *txt = (_InitBloomEffect) ? (new CTextureUser(_InitText)) : (new CTextureUser()); if (!_OriginalRenderTarget)
if(!((CDriverUser *) _Driver)->setRenderTarget(*txt, 0, 0, _WndWidth, _WndHeight))
{ {
nlwarning("setRenderTarget return false with initial texture for bloom effect\n"); NL3D::CTextureUser txt = (_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser());
return; 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 +375,13 @@ void CBloomEffect::endBloom() // clientcfg
if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0) if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0)
return; return;
CTextureUser *txt1 = (_InitBloomEffect) ? (new CTextureUser(_InitText)) : (new CTextureUser()); CTextureUser txt1 = _OriginalRenderTarget ? CTextureUser(_OriginalRenderTarget) : ((_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser()));
CTextureUser *txt2 = new CTextureUser(_BlurFinalTex); CTextureUser txt2(_BlurFinalTex);
CRect *rect1 = new CRect(0, 0, _WndWidth, _WndHeight); CRect rect1(0, 0, _WndWidth, _WndHeight);
CRect *rect2 = new CRect(0, 0, _BlurWidth, _BlurHeight); CRect rect2(0, 0, _BlurWidth, _BlurHeight);
// stretch rect // stretch rect
((CDriverUser *) _Driver)->stretchRect(_Scene, *txt1 , *rect1, ((CDriverUser *) _Driver)->stretchRect(_Scene, txt1 , rect1,
*txt2, *rect2); txt2, rect2);
// horizontal blur pass // horizontal blur pass
doBlur(true); doBlur(true);
@ -387,10 +391,6 @@ void CBloomEffect::endBloom() // clientcfg
// apply blur with a blend operation // apply blur with a blend operation
applyBlur(); applyBlur();
delete txt1;
delete txt2;
delete rect1;
delete rect2;
} }
//----------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------
@ -399,16 +399,30 @@ void CBloomEffect::applyBlur()
{ {
NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver();
// in opengl, display in init texture /*if (_OriginalRenderTarget)
if(_InitBloomEffect)
{ {
CTextureUser *txt = new CTextureUser(_InitText); CTextureUser txt(_OriginalRenderTarget);
if(!((CDriverUser *) _Driver)->setRenderTarget(*txt, 0, 0, _WndWidth, _WndHeight)) 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"); nlwarning("setRenderTarget return false with initial texture for bloom effect\n");
return; 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 // display blur texture
@ -463,7 +477,9 @@ void CBloomEffect::applyBlur()
void CBloomEffect::endInterfacesDisplayBloom() // clientcfg 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) if(!_Driver->supportBloomEffect() || !_Init)
return; return;
@ -475,9 +491,8 @@ void CBloomEffect::endInterfacesDisplayBloom() // clientcfg
return; return;
NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver();
CTextureUser *txt = new CTextureUser(); CTextureUser txtNull;
((CDriverUser *)_Driver)->setRenderTarget(*txt, 0, 0, 0, 0); ((CDriverUser *)_Driver)->setRenderTarget(txtNull, 0, 0, 0, 0);
delete txt;
// initialize texture coordinates // initialize texture coordinates
float newU = drvInternal->isTextureRectangle(_InitText) ? (float)_WndWidth : 1.f; float newU = drvInternal->isTextureRectangle(_InitText) ? (float)_WndWidth : 1.f;
@ -497,6 +512,8 @@ void CBloomEffect::endInterfacesDisplayBloom() // clientcfg
_Driver->drawQuad(_DisplayQuad, _DisplayInitMat); _Driver->drawQuad(_DisplayQuad, _DisplayInitMat);
_Driver->setMatrixMode3D(pCam); _Driver->setMatrixMode3D(pCam);
} }
_OriginalRenderTarget = NULL;
} }
@ -523,14 +540,13 @@ void CBloomEffect::doBlur(bool horizontalBlur)
} }
NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver();
CTextureUser *txt = new CTextureUser(endTexture); CTextureUser txt(endTexture);
// initialize render target // 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"); nlwarning("setRenderTarget return false with blur texture for bloom effect\n");
return; return;
} }
delete txt;
// initialize vertex program // initialize vertex program
drvInternal->activeVertexProgram(&TextureOffsetVertexProgram); drvInternal->activeVertexProgram(&TextureOffsetVertexProgram);
@ -579,10 +595,9 @@ void CBloomEffect::doBlur(bool horizontalBlur)
// disable render target and vertex program // disable render target and vertex program
drvInternal->activeVertexProgram(NULL); drvInternal->activeVertexProgram(NULL);
txt = new CTextureUser(); CTextureUser cu;
((CDriverUser *)_Driver)->setRenderTarget(*txt, 0, 0, 0, 0); ((CDriverUser *)_Driver)->setRenderTarget(cu, 0, 0, 0, 0);
_Driver->setMatrixMode3D(pCam); _Driver->setMatrixMode3D(pCam);
delete txt;
} }
}; // NL3D }; // NL3D

View file

@ -21,6 +21,7 @@
#include "nel/3d/index_buffer.h" #include "nel/3d/index_buffer.h"
#include "nel/3d/material.h" #include "nel/3d/material.h"
#include "nel/3d/frustum.h" #include "nel/3d/frustum.h"
#include "nel/3d/viewport.h"
#include "nel/misc/smart_ptr.h" #include "nel/misc/smart_ptr.h"
#include "nel/misc/debug.h" #include "nel/misc/debug.h"
@ -85,6 +86,10 @@ void CComputedString::render2D (IDriver& driver,
// get window size // get window size
uint32 wndWidth, wndHeight; uint32 wndWidth, wndHeight;
driver.getWindowSize(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. // scale to window size.
x*= wndWidth; x*= wndWidth;
z*= wndHeight; z*= wndHeight;

View file

@ -33,7 +33,7 @@ namespace NL3D
{ {
// *************************************************************************** // ***************************************************************************
const uint32 IDriver::InterfaceVersion = 0x6b; // added anisotropic filter const uint32 IDriver::InterfaceVersion = 0x6c; // pixel program interface
// *************************************************************************** // ***************************************************************************
IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" ) IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" )
@ -258,6 +258,11 @@ void IDriver::removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt)
{ {
_VtxPrgDrvInfos.erase(vtxPrgDrvInfoIt); _VtxPrgDrvInfos.erase(vtxPrgDrvInfoIt);
} }
// ***************************************************************************
void IDriver::removePixelPrgDrvInfoPtr(ItPixelPrgDrvInfoPtrList pixelPrgDrvInfoIt)
{
_PixelPrgDrvInfos.erase(pixelPrgDrvInfoIt);
}
// *************************************************************************** // ***************************************************************************
bool IDriver::invalidateShareTexture (ITexture &texture) bool IDriver::invalidateShareTexture (ITexture &texture)

View file

@ -193,6 +193,11 @@ CDriverD3D::CDriverD3D()
#else // NL_DISABLE_HARDWARE_VERTEX_PROGAM #else // NL_DISABLE_HARDWARE_VERTEX_PROGAM
_DisableHardwareVertexProgram = false; _DisableHardwareVertexProgram = false;
#endif // NL_DISABLE_HARDWARE_VERTEX_PROGAM #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 #ifdef NL_DISABLE_HARDWARE_VERTEX_ARRAY_AGP
_DisableHardwareVertexArrayAGP = true; _DisableHardwareVertexArrayAGP = true;
#else // NL_DISABLE_HARDWARE_VERTEX_ARRAY_AGP #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 #endif // NL_FORCE_TEXTURE_STAGE_COUNT
_VertexProgram = !_DisableHardwareVertexProgram && ((caps.VertexShaderVersion&0xffff) >= 0x0100); _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; _MaxVerticesByVertexBufferHard = caps.MaxVertexIndex;
_MaxLight = caps.MaxActiveLights; _MaxLight = caps.MaxActiveLights;
if(_MaxLight > 0xFF) _MaxLight = 3; if(_MaxLight > 0xFF) _MaxLight = 3;
if (_PixelShader) if (_PixelProgram)
{ {
_MaxNumPerStageConstantLighted = _NbNeLTextureStages; _MaxNumPerStageConstantLighted = _NbNeLTextureStages;
_MaxNumPerStageConstantUnlighted = _NbNeLTextureStages; _MaxNumPerStageConstantUnlighted = _NbNeLTextureStages;
@ -2016,6 +2023,8 @@ bool CDriverD3D::swapBuffers()
// Reset vertex program // Reset vertex program
setVertexProgram (NULL, NULL); setVertexProgram (NULL, NULL);
// Reset pixel program
setPixelShader (NULL);
if (_VBHardProfiling) if (_VBHardProfiling)
{ {
@ -2987,7 +2996,7 @@ bool CDriverD3D::stretchRect(ITexture * srcText, NLMISC::CRect &srcRect, ITextur
bool CDriverD3D::supportBloomEffect() const bool CDriverD3D::supportBloomEffect() const
{ {
return isVertexProgramSupported(); return supportVertexProgram();
} }
// *************************************************************************** // ***************************************************************************
@ -3330,9 +3339,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); return _PixelShaderVersion >= D3DPS_VERSION(1, 1);
} }
@ -3618,7 +3627,7 @@ void CDriverD3D::CVertexProgramPtrState::apply(CDriverD3D *driver)
void CDriverD3D::CPixelShaderPtrState::apply(CDriverD3D *driver) void CDriverD3D::CPixelShaderPtrState::apply(CDriverD3D *driver)
{ {
H_AUTO_D3D(CDriverD3D_CPixelShaderPtrState); H_AUTO_D3D(CDriverD3D_CPixelShaderPtrState);
if (!driver->supportPixelShaders()) return; if (!driver->supportPixelProgram()) return;
driver->_DeviceInterface->SetPixelShader(PixelShader); driver->_DeviceInterface->SetPixelShader(PixelShader);
} }

View file

@ -240,6 +240,19 @@ public:
CVertexProgamDrvInfosD3D(IDriver *drv, ItVtxPrgDrvInfoPtrList it); CVertexProgamDrvInfosD3D(IDriver *drv, ItVtxPrgDrvInfoPtrList it);
~CVertexProgamDrvInfosD3D(); ~CVertexProgamDrvInfosD3D();
}; };
// ***************************************************************************
class CPixelProgramDrvInfosD3D : public IPixelProgramDrvInfos
{
public:
// The shader
IDirect3DPixelShader9 *Shader;
CPixelProgramDrvInfosD3D(IDriver *drv, ItPixelPrgDrvInfoPtrList it);
~CPixelProgramDrvInfosD3D();
};
// *************************************************************************** // ***************************************************************************
@ -773,6 +786,7 @@ public:
// Driver parameters // Driver parameters
virtual void disableHardwareVertexProgram(); virtual void disableHardwareVertexProgram();
virtual void disableHardwarePixelProgram();
virtual void disableHardwareIndexArrayAGP(); virtual void disableHardwareIndexArrayAGP();
virtual void disableHardwareVertexArrayAGP(); virtual void disableHardwareVertexArrayAGP();
virtual void disableHardwareTextureShader(); virtual void disableHardwareTextureShader();
@ -841,6 +855,7 @@ public:
// todo hulud d3d buffers // todo hulud d3d buffers
virtual void getZBufferPart (std::vector<float> &zbuffer, NLMISC::CRect &rect); 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 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, virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y, uint32 width,
uint32 height, uint32 mipmapLevel); uint32 height, uint32 mipmapLevel);
virtual bool getRenderTargetSize (uint32 &width, uint32 &height); virtual bool getRenderTargetSize (uint32 &width, uint32 &height);
@ -959,9 +974,9 @@ public:
virtual bool supportTextureShaders() const {return false;}; virtual bool supportTextureShaders() const {return false;};
virtual bool supportMADOperator() const; virtual bool supportMADOperator() const;
// todo hulud d3d adressing mode // todo hulud d3d adressing mode
virtual bool isWaterShaderSupported() const; virtual bool supportWaterShader() const;
// todo hulud d3d adressing mode // 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 // todo hulud d3d adressing mode
virtual void setMatrix2DForTextureOffsetAddrMode(const uint /* stage */, const float /* mat */[4]) {} virtual void setMatrix2DForTextureOffsetAddrMode(const uint /* stage */, const float /* mat */[4]) {}
@ -992,9 +1007,12 @@ public:
virtual void endMaterialMultiPass(); virtual void endMaterialMultiPass();
// Vertex program // Vertex program
virtual bool isVertexProgramSupported () const; virtual bool supportVertexProgram () const;
virtual bool supportPixelProgram () const;
virtual bool supportPixelProgram (CPixelProgram::TProfile profile) const;
virtual bool isVertexProgramEmulated () const; virtual bool isVertexProgramEmulated () const;
virtual bool activeVertexProgram (CVertexProgram *program); virtual bool activeVertexProgram (CVertexProgram *program);
virtual bool activePixelProgram (CPixelProgram *program);
virtual void setConstant (uint index, float, float, float, float); virtual void setConstant (uint index, float, float, float, float);
virtual void setConstant (uint index, double, double, double, double); 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::CVector& value);
@ -1006,6 +1024,15 @@ public:
virtual void enableVertexProgramDoubleSidedColor(bool doubleSided); virtual void enableVertexProgramDoubleSidedColor(bool doubleSided);
virtual bool supportVertexProgramDoubleSidedColor() const; virtual bool supportVertexProgramDoubleSidedColor() const;
// Pixel program
virtual void setPixelProgramConstant (uint index, float, float, float, float);
virtual void setPixelProgramConstant (uint index, double, double, double, double);
virtual void setPixelProgramConstant (uint index, const NLMISC::CVector& value);
virtual void setPixelProgramConstant (uint index, const NLMISC::CVectorD& value);
virtual void setPixelProgramConstant (uint index, uint num, const float *src);
virtual void setPixelProgramConstant (uint index, uint num, const double *src);
virtual void setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform);
// Occlusion query // Occlusion query
virtual bool supportOcclusionQuery() const; virtual bool supportOcclusionQuery() const;
virtual IOcclusionQuery *createOcclusionQuery(); virtual IOcclusionQuery *createOcclusionQuery();
@ -1040,8 +1067,6 @@ public:
uint32 getMaxVertexIndex() const { return _MaxVertexIndex; } uint32 getMaxVertexIndex() const { return _MaxVertexIndex; }
bool supportPixelShaders() const { return _PixelShader; }
// *** Inline info // *** Inline info
uint inlGetNumTextStages() const { return _NbNeLTextureStages; } uint inlGetNumTextStages() const { return _NbNeLTextureStages; }
@ -1892,6 +1917,15 @@ public:
return d3dtex; 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*)(IPixelProgramDrvInfos*)(pixelProgram._DrvInfo);
return d3dPixelProgram;
}
// Get the d3dtext mirror of an existing setuped vertex program. // Get the d3dtext mirror of an existing setuped vertex program.
static inline CVertexProgamDrvInfosD3D* getVertexProgramD3D(CVertexProgram& vertexProgram) static inline CVertexProgamDrvInfosD3D* getVertexProgramD3D(CVertexProgram& vertexProgram)
{ {
@ -2197,8 +2231,10 @@ private:
bool _ForceDXTCCompression:1; bool _ForceDXTCCompression:1;
bool _TextureCubeSupported; bool _TextureCubeSupported;
bool _VertexProgram; bool _VertexProgram;
bool _PixelShader; bool _PixelProgram;
uint16 _PixelProgramVersion;
bool _DisableHardwareVertexProgram; bool _DisableHardwareVertexProgram;
bool _DisableHardwarePixelProgram;
bool _DisableHardwareVertexArrayAGP; bool _DisableHardwareVertexArrayAGP;
bool _DisableHardwareIndexArrayAGP; bool _DisableHardwareIndexArrayAGP;
bool _DisableHardwarePixelShader; bool _DisableHardwarePixelShader;

View file

@ -567,7 +567,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat)
normalShaderDesc.TexEnvMode[stage] = mat.getTexEnvMode(uint8(stage)); normalShaderDesc.TexEnvMode[stage] = mat.getTexEnvMode(uint8(stage));
} }
if (_PixelShader) if (_PixelProgram)
{ {
#ifdef NL_DEBUG_D3D #ifdef NL_DEBUG_D3D
// Check, should not occured // Check, should not occured
@ -648,7 +648,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat)
// Must separate texture setup and texture activation in 2 "for"... // Must separate texture setup and texture activation in 2 "for"...
// because setupTexture() may disable all stage. // because setupTexture() may disable all stage.
if (matShader == CMaterial::Normal) if (matShader == CMaterial::Normal || matShader == CMaterial::PostProcessing)
{ {
uint stage; uint stage;
for(stage=0 ; stage<maxTexture; ++stage) for(stage=0 ; stage<maxTexture; ++stage)
@ -668,7 +668,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat)
// Don't do it also for Specular because the EnvFunction and the TexGen may be special. // Don't do it also for Specular because the EnvFunction and the TexGen may be special.
{ {
H_AUTO_D3D(CDriverD3D_setupMaterial_normalShaderActivateTextures) H_AUTO_D3D(CDriverD3D_setupMaterial_normalShaderActivateTextures)
if(matShader == CMaterial::Normal) if (matShader == CMaterial::Normal || matShader == CMaterial::PostProcessing)
{ {
uint stage; uint stage;
for(stage=0 ; stage<maxTexture; ++stage) for(stage=0 ; stage<maxTexture; ++stage)
@ -933,7 +933,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat)
activeShader (NULL); activeShader (NULL);
/* If unlighted trick is needed, set the shader later */ /* If unlighted trick is needed, set the shader later */
if (!pShader->NeedsConstantForDiffuse && _PixelShader) if (!pShader->NeedsConstantForDiffuse && _PixelProgram)
setPixelShader (pShader->PixelShader); setPixelShader (pShader->PixelShader);
} }
break; break;
@ -2019,7 +2019,7 @@ void CDriverD3D::endMaterialMultiPass()
bool CDriverD3D::supportCloudRenderSinglePass () const bool CDriverD3D::supportCloudRenderSinglePass () const
{ {
H_AUTO_D3D(CDriver3D_supportCloudRenderSinglePass); H_AUTO_D3D(CDriver3D_supportCloudRenderSinglePass);
return _PixelShader; return _PixelProgram;
} }
// *************************************************************************** // ***************************************************************************

View file

@ -0,0 +1,295 @@
/** \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, ItPixelPrgDrvInfoPtrList it) : IPixelProgramDrvInfos (drv, it)
{
H_AUTO_D3D(CPixelProgramDrvInfosD3D_CPixelProgamDrvInfosD3D)
Shader = NULL;
}
// ***************************************************************************
CPixelProgramDrvInfosD3D::~CPixelProgramDrvInfosD3D()
{
H_AUTO_D3D(CPixelProgramDrvInfosD3D_CPixelProgramDrvInfosD3DDtor)
if (Shader)
Shader->Release();
}
// ***************************************************************************
bool CDriverD3D::supportPixelProgram () const
{
H_AUTO_D3D(CDriverD3D_supportPixelProgram)
return _PixelProgram;
}
bool CDriverD3D::supportPixelProgram (CPixelProgram::TProfile profile) const
{
H_AUTO_D3D(CDriverD3D_supportPixelProgram_profile)
return ((profile & 0xFFFF0000) == 0xD3D00000)
&& (_PixelProgramVersion >= (uint16)(profile & 0x0000FFFF));
}
// ***************************************************************************
bool CDriverD3D::activePixelProgram(CPixelProgram *program)
{
H_AUTO_D3D(CDriverD3D_activePixelProgram )
if (_DisableHardwarePixelProgram)
return false;
// Setup or unsetup ?
if (program)
{
// Program setuped ?
if (program->_DrvInfo==NULL)
{
_PixelPrgDrvInfos.push_front (NULL);
ItPixelPrgDrvInfoPtrList itPix = _PixelPrgDrvInfos.begin();
*itPix = new CPixelProgramDrvInfosD3D(this, itPix);
// Create a driver info structure
program->_DrvInfo = *itPix;
const std::string &dest = program->getProgram();
LPD3DXBUFFER pShader;
LPD3DXBUFFER pErrorMsgs;
if (D3DXAssembleShader (dest.c_str(), dest.size(), 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 the pixel program
if (program)
{
CPixelProgramDrvInfosD3D *info = static_cast<CPixelProgramDrvInfosD3D *>((IPixelProgramDrvInfos*)program->_DrvInfo);
setPixelShader (info->Shader);
float z = 0;
float o = 1;
setRenderState (D3DRS_FOGSTART, *((DWORD*) (&o)));
setRenderState (D3DRS_FOGEND, *((DWORD*) (&z)));
}
else
{
setPixelShader (NULL);
// Set the old fog range
setRenderState (D3DRS_FOGSTART, *((DWORD*) (&_FogStart)));
setRenderState (D3DRS_FOGEND, *((DWORD*) (&_FogEnd)));
}
return true;
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstant (uint index, float f0, float f1, float f2, float f3)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstant)
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel programs available!!");
#endif
return;
}
const float tabl[4] = {f0, f1, f2, f3};
setPixelShaderConstant (index, tabl);
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstant (uint index, double d0, double d1, double d2, double d3)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstant )
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel programs available!!");
#endif
return;
}
const float tabl[4] = {(float)d0, (float)d1, (float)d2, (float)d3};
setPixelShaderConstant (index, tabl);
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstant (uint index, const NLMISC::CVector& value)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstant )
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel programs available!!");
#endif
return;
}
const float tabl[4] = {value.x, value.y, value.z, 0};
setPixelShaderConstant (index, tabl);
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstant (uint index, const NLMISC::CVectorD& value)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstant )
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel programs available!!");
#endif
return;
}
const float tabl[4] = {(float)value.x, (float)value.y, (float)value.z, 0};
setPixelShaderConstant (index, tabl);
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstant (uint index, uint num, const float *src)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstant )
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel programs available!!");
#endif
return;
}
uint i;
for (i=0; i<num; i++)
setPixelShaderConstant (index+i, src+i*4);
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstant (uint index, uint num, const double *src)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstant )
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel 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]};
setPixelShaderConstant (index+i, tabl);
src += 4;
}
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstantMatrix)
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel programs available!!");
#endif
return;
}
D3DXMATRIX mat;
D3DXMATRIX *matPtr;
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;
}
}
setPixelProgramConstant (index, matPtr->_11, matPtr->_21, matPtr->_31, matPtr->_41);
setPixelProgramConstant (index+1, matPtr->_12, matPtr->_22, matPtr->_32, matPtr->_42);
setPixelProgramConstant (index+2, matPtr->_13, matPtr->_23, matPtr->_33, matPtr->_43);
setPixelProgramConstant (index+3, matPtr->_14, matPtr->_24, matPtr->_34, matPtr->_44);
}
// ***************************************************************************
void CDriverD3D::disableHardwarePixelProgram()
{
H_AUTO_D3D(CDriverD3D_disableHardwarePixelProgram)
_DisableHardwarePixelProgram = true;
_PixelProgram = false;
}
} // NL3D

View file

@ -1187,6 +1187,11 @@ bool CDriverD3D::setRenderTarget (ITexture *tex, uint32 /* x */, uint32 /* y */,
return true; return true;
} }
ITexture *CDriverD3D::getRenderTarget() const
{
return _RenderTarget.Texture;
}
// *************************************************************************** // ***************************************************************************
bool CDriverD3D::copyTargetToTexture (ITexture * /* tex */, uint32 /* offsetx */, uint32 /* offsety */, uint32 /* x */, uint32 /* y */, uint32 /* width */, bool CDriverD3D::copyTargetToTexture (ITexture * /* tex */, uint32 /* offsetx */, uint32 /* offsety */, uint32 /* x */, uint32 /* y */, uint32 /* width */,

View file

@ -43,9 +43,9 @@ CVertexProgamDrvInfosD3D::~CVertexProgamDrvInfosD3D()
// *************************************************************************** // ***************************************************************************
bool CDriverD3D::isVertexProgramSupported () const bool CDriverD3D::supportVertexProgram () const
{ {
H_AUTO_D3D(CDriverD3D_isVertexProgramSupported ) H_AUTO_D3D(CDriverD3D_supportVertexProgram )
return _VertexProgram; return _VertexProgram;
} }

View file

@ -263,8 +263,6 @@ CDriverGL::CDriverGL()
_CurrentFogColor[2]= 0; _CurrentFogColor[2]= 0;
_CurrentFogColor[3]= 0; _CurrentFogColor[3]= 0;
_RenderTargetFBO = false;
_LightSetupDirty= false; _LightSetupDirty= false;
_ModelViewMatrixDirty= false; _ModelViewMatrixDirty= false;
_RenderSetupDirty= false; _RenderSetupDirty= false;
@ -482,6 +480,7 @@ bool CDriverGL::setupDisplay()
} }
_VertexProgramEnabled= false; _VertexProgramEnabled= false;
_PixelProgramEnabled= false;
_LastSetupGLArrayVertexProgram= false; _LastSetupGLArrayVertexProgram= false;
// Init VertexArrayRange according to supported extenstion. // Init VertexArrayRange according to supported extenstion.
@ -690,7 +689,7 @@ bool CDriverGL::stretchRect(ITexture * /* srcText */, NLMISC::CRect &/* srcRect
// *************************************************************************** // ***************************************************************************
bool CDriverGL::supportBloomEffect() const 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 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()))); && (!isPowerOf2(tex->getWidth()) || !isPowerOf2(tex->getHeight())));
} }
@ -737,6 +736,12 @@ void CDriverGL::disableHardwareVertexProgram()
_Extensions.DisableHardwareVertexProgram= true; _Extensions.DisableHardwareVertexProgram= true;
} }
void CDriverGL::disableHardwarePixelProgram()
{
H_AUTO_OGL(CDriverGL_disableHardwarePixelProgram)
_Extensions.DisableHardwarePixelProgram= true;
}
// *************************************************************************** // ***************************************************************************
void CDriverGL::disableHardwareVertexArrayAGP() void CDriverGL::disableHardwareVertexArrayAGP()
{ {
@ -854,6 +859,7 @@ bool CDriverGL::swapBuffers()
// Reset texture shaders // Reset texture shaders
//resetTextureShaders(); //resetTextureShaders();
activeVertexProgram(NULL); activeVertexProgram(NULL);
activePixelProgram(NULL);
#ifndef USE_OPENGLES #ifndef USE_OPENGLES
/* Yoyo: must do this (GeForce bug ??) else weird results if end render with a VBHard. /* Yoyo: must do this (GeForce bug ??) else weird results if end render with a VBHard.
@ -1535,9 +1541,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; if(_Extensions.ARBFragmentProgram && ARBWaterShader[0] != 0) return true;
@ -1547,9 +1553,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) if (_Extensions.NVTextureShader)
{ {

View file

@ -308,6 +308,7 @@ public:
virtual bool init (uint windowIcon = 0, emptyProc exitFunc = 0); virtual bool init (uint windowIcon = 0, emptyProc exitFunc = 0);
virtual void disableHardwareVertexProgram(); virtual void disableHardwareVertexProgram();
virtual void disableHardwarePixelProgram();
virtual void disableHardwareVertexArrayAGP(); virtual void disableHardwareVertexArrayAGP();
virtual void disableHardwareTextureShader(); virtual void disableHardwareTextureShader();
@ -565,6 +566,8 @@ public:
virtual bool setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width, uint32 height, virtual bool setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width, uint32 height,
uint32 mipmapLevel, uint32 cubeFace); uint32 mipmapLevel, uint32 cubeFace);
virtual ITexture *getRenderTarget() const;
virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y, virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y,
uint32 width, uint32 height, uint32 mipmapLevel); uint32 width, uint32 height, uint32 mipmapLevel);
@ -602,9 +605,9 @@ public:
// @{ // @{
virtual bool supportTextureShaders() const; 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]); virtual void setMatrix2DForTextureOffsetAddrMode(const uint stage, const float mat[4]);
// @} // @}
@ -694,6 +697,7 @@ private:
virtual class IVertexBufferHardGL *createVertexBufferHard(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb); virtual class IVertexBufferHardGL *createVertexBufferHard(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb);
friend class CTextureDrvInfosGL; friend class CTextureDrvInfosGL;
friend class CVertexProgamDrvInfosGL; friend class CVertexProgamDrvInfosGL;
friend class CPixelProgamDrvInfosGL;
private: private:
// Version of the driver. Not the interface version!! Increment when implementation of the driver change. // Version of the driver. Not the interface version!! Increment when implementation of the driver change.
@ -889,7 +893,7 @@ private:
// viewport before call to setRenderTarget, if BFO extension is supported // viewport before call to setRenderTarget, if BFO extension is supported
CViewport _OldViewport; CViewport _OldViewport;
bool _RenderTargetFBO; CSmartPtr<ITexture> _RenderTargetFBO;
// Num lights return by GL_MAX_LIGHTS // Num lights return by GL_MAX_LIGHTS
@ -1303,9 +1307,12 @@ private:
/// \name Vertex program interface /// \name Vertex program interface
// @{ // @{
bool isVertexProgramSupported () const; bool supportVertexProgram () const;
bool supportPixelProgram () const;
bool supportPixelProgram (CPixelProgram::TProfile profile) const;
bool isVertexProgramEmulated () const; bool isVertexProgramEmulated () const;
bool activeVertexProgram (CVertexProgram *program); bool activeVertexProgram (CVertexProgram *program);
bool activePixelProgram (CPixelProgram *program);
void setConstant (uint index, float, float, float, float); void setConstant (uint index, float, float, float, float);
void setConstant (uint index, double, double, double, double); void setConstant (uint index, double, double, double, double);
void setConstant (uint indexStart, const NLMISC::CVector& value); void setConstant (uint indexStart, const NLMISC::CVector& value);
@ -1316,6 +1323,15 @@ private:
void setConstantFog (uint index); void setConstantFog (uint index);
void enableVertexProgramDoubleSidedColor(bool doubleSided); void enableVertexProgramDoubleSidedColor(bool doubleSided);
bool supportVertexProgramDoubleSidedColor() const; bool supportVertexProgramDoubleSidedColor() const;
// Pixel program
virtual void setPixelProgramConstant (uint index, float, float, float, float);
virtual void setPixelProgramConstant (uint index, double, double, double, double);
virtual void setPixelProgramConstant (uint index, const NLMISC::CVector& value);
virtual void setPixelProgramConstant (uint index, const NLMISC::CVectorD& value);
virtual void setPixelProgramConstant (uint index, uint num, const float *src);
virtual void setPixelProgramConstant (uint index, uint num, const double *src);
virtual void setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform);
virtual bool supportMADOperator() const ; virtual bool supportMADOperator() const ;
@ -1330,6 +1346,12 @@ private:
//@} //@}
/// \name Pixel program implementation
// @{
bool activeARBPixelProgram (CPixelProgram *program);
bool setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, bool &specularWritten*/);
//@}
/// \fallback for material shaders /// \fallback for material shaders
// @{ // @{
@ -1342,15 +1364,27 @@ private:
// Don't use glIsEnabled, too slow. // Don't use glIsEnabled, too slow.
return _VertexProgramEnabled; return _VertexProgramEnabled;
} }
bool isPixelProgramEnabled () const
{
// Don't use glIsEnabled, too slow.
return _PixelProgramEnabled;
}
// Track state of activeVertexProgram() // Track state of activeVertexProgram()
bool _VertexProgramEnabled; bool _VertexProgramEnabled;
// Track state of activePixelProgram()
bool _PixelProgramEnabled;
// Say if last setupGlArrays() was a VertexProgram setup. // Say if last setupGlArrays() was a VertexProgram setup.
bool _LastSetupGLArrayVertexProgram; bool _LastSetupGLArrayVertexProgram;
// The last vertex program that was setupped // The last vertex program that was setupped
NLMISC::CRefPtr<CVertexProgram> _LastSetuppedVP; NLMISC::CRefPtr<CVertexProgram> _LastSetuppedVP;
// The last pixel program that was setupped
NLMISC::CRefPtr<CPixelProgram> _LastSetuppedPP;
bool _ForceDXTCCompression; bool _ForceDXTCCompression;
/// Divisor for textureResize (power). /// Divisor for textureResize (power).
uint _ForceTextureResizePower; uint _ForceTextureResizePower;
@ -1520,6 +1554,17 @@ public:
CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it); CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it);
}; };
// ***************************************************************************
class CPixelProgamDrvInfosGL : public IPixelProgramDrvInfos
{
public:
// The GL Id.
GLuint ID;
// The gl id is auto created here.
CPixelProgamDrvInfosGL (CDriverGL *drv, ItPixelPrgDrvInfoPtrList it);
};
#ifdef NL_STATIC #ifdef NL_STATIC
} // NLDRIVERGL/ES } // NLDRIVERGL/ES
#endif #endif

View file

@ -1225,6 +1225,15 @@ static bool setupARBFragmentProgram(const char *glext)
return true; 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) static bool setupARBVertexBufferObject(const char *glext)
{ {
@ -1560,6 +1569,19 @@ void registerGlExtensions(CGlExtensions &ext)
ext.EXTVertexShader = false; ext.EXTVertexShader = false;
ext.ARBVertexProgram = 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.OESDrawTexture = setupOESDrawTexture(glext);
ext.OESMapBuffer = setupOESMapBuffer(glext); ext.OESMapBuffer = setupOESMapBuffer(glext);
@ -1571,14 +1593,12 @@ void registerGlExtensions(CGlExtensions &ext)
ext.NVTextureShader = setupNVTextureShader(glext); ext.NVTextureShader = setupNVTextureShader(glext);
ext.ATIEnvMapBumpMap = setupATIEnvMapBumpMap(glext); ext.ATIEnvMapBumpMap = setupATIEnvMapBumpMap(glext);
ext.ATIFragmentShader = setupATIFragmentShader(glext); ext.ATIFragmentShader = setupATIFragmentShader(glext);
ext.ARBFragmentProgram = setupARBFragmentProgram(glext);
} }
else else
{ {
ext.ATIEnvMapBumpMap = false; ext.ATIEnvMapBumpMap = false;
ext.NVTextureShader = false; ext.NVTextureShader = false;
ext.ATIFragmentShader = 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. // For now, the only way to know if emulation, is to test some extension which exist only on GeForce3.

View file

@ -103,6 +103,9 @@ struct CGlExtensions
bool ARBTextureNonPowerOfTwo; bool ARBTextureNonPowerOfTwo;
bool ARBMultisample; bool ARBMultisample;
// NV Pixel Programs
bool NVFragmentProgram2;
bool OESDrawTexture; bool OESDrawTexture;
bool OESMapBuffer; bool OESMapBuffer;
@ -111,6 +114,7 @@ public:
/// \name Disable Hardware feature. False by default. setuped by IDriver /// \name Disable Hardware feature. False by default. setuped by IDriver
// @{ // @{
bool DisableHardwareVertexProgram; bool DisableHardwareVertexProgram;
bool DisableHardwarePixelProgram;
bool DisableHardwareVertexArrayAGP; bool DisableHardwareVertexArrayAGP;
bool DisableHardwareTextureShader; bool DisableHardwareTextureShader;
// @} // @}
@ -174,6 +178,7 @@ public:
/// \name Disable Hardware feature. False by default. setuped by IDriver /// \name Disable Hardware feature. False by default. setuped by IDriver
DisableHardwareVertexProgram= false; DisableHardwareVertexProgram= false;
DisableHardwarePixelProgram= false;
DisableHardwareVertexArrayAGP= false; DisableHardwareVertexArrayAGP= false;
DisableHardwareTextureShader= false; DisableHardwareTextureShader= false;
} }
@ -206,6 +211,7 @@ public:
result += NVTextureShader ? "NVTextureShader " : ""; result += NVTextureShader ? "NVTextureShader " : "";
result += ATIFragmentShader ? "ATIFragmentShader " : ""; result += ATIFragmentShader ? "ATIFragmentShader " : "";
result += ARBFragmentProgram ? "ARBFragmentProgram " : ""; result += ARBFragmentProgram ? "ARBFragmentProgram " : "";
result += NVFragmentProgram2 ? "NVFragmentProgram2 " : "";
result += ARBVertexProgram ? "ARBVertexProgram " : ""; result += ARBVertexProgram ? "ARBVertexProgram " : "";
result += NVVertexProgram ? "NVVertexProgram " : ""; result += NVVertexProgram ? "NVVertexProgram " : "";
result += EXTVertexShader ? "EXTVertexShader " : ""; result += EXTVertexShader ? "EXTVertexShader " : "";

View file

@ -0,0 +1,336 @@
/** \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, ItPixelPrgDrvInfoPtrList it) : IPixelProgramDrvInfos (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() const
{
H_AUTO_OGL(CPixelProgamDrvInfosGL_supportPixelProgram)
return _Extensions.ARBFragmentProgram;
}
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::activeARBPixelProgram(CPixelProgram *program)
{
H_AUTO_OGL(CDriverGL_activeARBPixelProgram)
// Setup or unsetup ?
if (program)
{
// Driver info
CPixelProgamDrvInfosGL *drvInfo;
// Program setuped ?
if (program->_DrvInfo==NULL)
{
// Insert into driver list. (so it is deleted when driver is deleted).
ItPixelPrgDrvInfoPtrList it= _PixelPrgDrvInfos.insert(_PixelPrgDrvInfos.end(), (NL3D::IPixelProgramDrvInfos*)NULL);
// Create a driver info
*it = drvInfo = new CPixelProgamDrvInfosGL (this, it);
// Set the pointer
program->_DrvInfo=drvInfo;
if(!setupARBPixelProgram(program, drvInfo->ID))
{
delete drvInfo;
program->_DrvInfo = NULL;
_PixelPrgDrvInfos.erase(it);
return false;
}
}
else
{
// Cast the driver info pointer
drvInfo=safe_cast<CPixelProgamDrvInfosGL*>((IPixelProgramDrvInfos*)program->_DrvInfo);
}
glEnable( GL_FRAGMENT_PROGRAM_ARB );
_PixelProgramEnabled = true;
nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, drvInfo->ID );
glDisable( GL_COLOR_SUM_ARB ); // no specular written
_LastSetuppedPP = program;
}
else
{
glDisable( GL_FRAGMENT_PROGRAM_ARB );
glDisable( GL_COLOR_SUM_ARB );
_PixelProgramEnabled = false;
}
return true;
}
// ***************************************************************************
bool CDriverGL::setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, bool &specularWritten*/)
{
H_AUTO_OGL(CDriverGL_setupARBPixelProgram)
const std::string &code = program->getProgram();
nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, id);
glGetError();
nglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, code.size(), code.c_str() );
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) code.size());
uint line = 0;
const char *lineStart = program->getProgram().c_str();
for(uint k = 0; k < (uint) position; ++k)
{
if (code[k] == '\n')
{
lineStart = code.c_str() + k;
++line;
}
}
nlwarning("ARB fragment program parse error at line %d.", (int) line);
// search end of line
const char *lineEnd = code.c_str() + code.size();
for(uint k = position; k < code.size(); ++k)
{
if (code[k] == '\n')
{
lineEnd = code.c_str() + 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;
}
return true;
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstant (uint index, float f0, float f1, float f2, float f3)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
if (_Extensions.ARBFragmentProgram)
nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, f0, f1, f2, f3);
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstant (uint index, double d0, double d1, double d2, double d3)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
if (_Extensions.ARBFragmentProgram)
nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, d0, d1, d2, d3);
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVector& value)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
if (_Extensions.ARBFragmentProgram)
nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0);
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVectorD& value)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
if (_Extensions.ARBFragmentProgram)
nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0);
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstant (uint index, uint num, const float *src)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
if (_Extensions.ARBFragmentProgram)
{
for(uint k = 0; k < num; ++k)
{
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k);
}
}
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstant (uint index, uint num, const double *src)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
if (_Extensions.ARBFragmentProgram)
{
for(uint k = 0; k < num; ++k)
{
nglProgramEnvParameter4dvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k);
}
}
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstantMatrix)
if (_Extensions.ARBFragmentProgram)
{
// 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);
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index, matDatas);
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 1, matDatas + 4);
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 2, matDatas + 8);
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 3, matDatas + 12);
}
}
#ifdef NL_STATIC
} // NLDRIVERGL/ES
#endif
} // NL3D

View file

@ -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)); newVP.init(0, 0, ((float)width/(float)w), ((float)height/(float)h));
setupViewport(newVP); setupViewport(newVP);
_RenderTargetFBO = true; _RenderTargetFBO = tex;
return activeFrameBufferObject(tex); return activeFrameBufferObject(tex);
} }
@ -2343,7 +2343,7 @@ bool CDriverGL::setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width
setupViewport(_OldViewport); setupViewport(_OldViewport);
_OldViewport = _CurrViewport; _OldViewport = _CurrViewport;
_RenderTargetFBO = false; _RenderTargetFBO = NULL;
return false; return false;
} }
@ -2356,12 +2356,17 @@ bool CDriverGL::setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width
// Update the scissor // Update the scissor
setupScissor (_CurrScissor); setupScissor (_CurrScissor);
_RenderTargetFBO = false; _RenderTargetFBO = NULL;
_OldViewport = _CurrViewport; _OldViewport = _CurrViewport;
return true; return true;
} }
ITexture *CDriverGL::getRenderTarget() const
{
return _RenderTargetFBO ? _RenderTargetFBO : _TextureTarget;
}
// *************************************************************************** // ***************************************************************************
bool CDriverGL::copyTargetToTexture (ITexture *tex, bool CDriverGL::copyTargetToTexture (ITexture *tex,

View file

@ -70,9 +70,9 @@ CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInf
// *************************************************************************** // ***************************************************************************
bool CDriverGL::isVertexProgramSupported () const bool CDriverGL::supportVertexProgram () const
{ {
H_AUTO_OGL(CVertexProgamDrvInfosGL_isVertexProgramSupported) H_AUTO_OGL(CVertexProgamDrvInfosGL_supportVertexProgram)
return _Extensions.NVVertexProgram || _Extensions.EXTVertexShader || _Extensions.ARBVertexProgram; return _Extensions.NVVertexProgram || _Extensions.EXTVertexShader || _Extensions.ARBVertexProgram;
} }

View file

@ -213,6 +213,12 @@ void CDriverUser::disableHardwareVertexProgram()
_Driver->disableHardwareVertexProgram(); _Driver->disableHardwareVertexProgram();
} }
void CDriverUser::disableHardwarePixelProgram()
{
NL3D_HAUTO_UI_DRIVER;
_Driver->disableHardwarePixelProgram();
}
void CDriverUser::disableHardwareVertexArrayAGP() void CDriverUser::disableHardwareVertexArrayAGP()
{ {
NL3D_HAUTO_UI_DRIVER; NL3D_HAUTO_UI_DRIVER;

View file

@ -363,6 +363,7 @@ void CFlareModel::traverseRender()
} }
// setup driver // setup driver
drv->activeVertexProgram(NULL); drv->activeVertexProgram(NULL);
drv->activePixelProgram(NULL);
drv->setupModelMatrix(fs->getLookAtMode() ? CMatrix::Identity : getWorldMatrix()); 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 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 // we setup Z to be (near + far) / 2, and setup x and y to get the screen coordinates we want
@ -565,6 +566,7 @@ void CFlareModel::updateOcclusionQueryBegin(IDriver *drv)
{ {
nlassert(drv); nlassert(drv);
drv->activeVertexProgram(NULL); drv->activeVertexProgram(NULL);
drv->activePixelProgram(NULL);
drv->setupModelMatrix(CMatrix::Identity); drv->setupModelMatrix(CMatrix::Identity);
initStatics(); initStatics();
drv->setColorMask(false, false, false, false); // don't write any pixel during the test drv->setColorMask(false, false, false, false); // don't write any pixel during the test
@ -661,6 +663,7 @@ void CFlareModel::occlusionTest(CMesh &mesh, IDriver &drv)
} }
drv.setColorMask(false, false, false, false); // don't write any pixel during the test drv.setColorMask(false, false, false, false); // don't write any pixel during the test
drv.activeVertexProgram(NULL); drv.activeVertexProgram(NULL);
drv.activePixelProgram(NULL);
setupOcclusionMeshMatrix(drv, *_Scene); setupOcclusionMeshMatrix(drv, *_Scene);
drv.activeVertexBuffer(const_cast<CVertexBuffer &>(mesh.getVertexBuffer())); drv.activeVertexBuffer(const_cast<CVertexBuffer &>(mesh.getVertexBuffer()));
// query drawn count // query drawn count

View file

@ -574,7 +574,7 @@ void CLandscape::setDriver(IDriver *drv)
// Does the driver support VertexShader??? // Does the driver support VertexShader???
// only if VP supported by GPU. // only if VP supported by GPU.
_VertexShaderOk= (_Driver->isVertexProgramSupported() && !_Driver->isVertexProgramEmulated()); _VertexShaderOk= (_Driver->supportVertexProgram() && !_Driver->isVertexProgramEmulated());
// Does the driver has sufficient requirements for Vegetable??? // Does the driver has sufficient requirements for Vegetable???

View file

@ -82,7 +82,7 @@ void CLandscapeVBAllocator::updateDriver(IDriver *driver)
deleteVertexProgram(); deleteVertexProgram();
// Then rebuild VB format, and VertexProgram, if needed. // Then rebuild VB format, and VertexProgram, if needed.
// Do it only if VP supported by GPU. // Do it only if VP supported by GPU.
setupVBFormatAndVertexProgram(_Driver->isVertexProgramSupported() && !_Driver->isVertexProgramEmulated()); setupVBFormatAndVertexProgram(_Driver->supportVertexProgram() && !_Driver->isVertexProgramEmulated());
// must reallocate the VertexBuffer. // must reallocate the VertexBuffer.
if( _NumVerticesAllocated>0 ) if( _NumVerticesAllocated>0 )

View file

@ -428,7 +428,7 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv,
{ {
// test if supported by driver // test if supported by driver
if (! if (!
(drv->isVertexProgramSupported() (drv->supportVertexProgram()
&& !drv->isVertexProgramEmulated() && !drv->isVertexProgramEmulated()
&& drv->supportPerPixelLighting(SpecularLighting) && drv->supportPerPixelLighting(SpecularLighting)
) )

View file

@ -287,7 +287,7 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene
// *************************************************************************** // ***************************************************************************
bool CMeshVPWindTree::begin(IDriver *driver, CScene *scene, CMeshBaseInstance *mbi, const NLMISC::CMatrix &invertedModelMat, const NLMISC::CVector & /*viewerPos*/) 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;
// precompute mesh // precompute mesh
@ -367,7 +367,7 @@ bool CMeshVPWindTree::supportMeshBlockRendering() const
// *************************************************************************** // ***************************************************************************
bool CMeshVPWindTree::isMBRVpOk(IDriver *driver) const bool CMeshVPWindTree::isMBRVpOk(IDriver *driver) const
{ {
return driver->isVertexProgramSupported() && !driver->isVertexProgramEmulated(); return driver->supportVertexProgram() && !driver->isVertexProgramEmulated();
} }
// *************************************************************************** // ***************************************************************************

View file

@ -0,0 +1,63 @@
/** \file pixel_program.cpp
* Pixel program definition
*
* $Id: pixel_program.cpp,v 1.1.2.1 2007/04/27 17:35:07 legallo Exp $
*/
/* 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
{
// ***************************************************************************
IPixelProgramDrvInfos::IPixelProgramDrvInfos (IDriver *drv, ItPixelPrgDrvInfoPtrList it)
{
_Driver= drv;
_DriverIterator= it;
}
// ***************************************************************************
IPixelProgramDrvInfos::~IPixelProgramDrvInfos ()
{
_Driver->removePixelPrgDrvInfoPtr (_DriverIterator);
}
// ***************************************************************************
CPixelProgram::CPixelProgram(const char* program) : _Program(program)
{
}
// ***************************************************************************
CPixelProgram::~CPixelProgram()
{
}
} // NL3D

View file

@ -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 bump is used, the matrix must be setupped each time (not a material field)
if (!_ForceBasicCaps && isMultiTextureEnabled() && _MainOp == EnvBumpMap) if (!_ForceBasicCaps && isMultiTextureEnabled() && _MainOp == EnvBumpMap)
{ {
if (driver->isTextureAddrModeSupported(CMaterial::OffsetTexture)) if (driver->supportTextureAddrMode(CMaterial::OffsetTexture))
{ {
CTextureBump *tb = dynamic_cast<CTextureBump *>((ITexture *) _Texture2); CTextureBump *tb = dynamic_cast<CTextureBump *>((ITexture *) _Texture2);
if (tb != NULL) if (tb != NULL)
@ -858,7 +858,7 @@ void CPSMultiTexturedParticle::setupMaterial(ITexture *primary, IDriver *driver,
} }
else 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); CTextureBump *tb = dynamic_cast<CTextureBump *>((ITexture *) _Texture2);
if (tb != NULL) if (tb != NULL)
@ -917,7 +917,7 @@ void CPSMultiTexturedParticle::setupMultiTexEnv(TOperator op, ITexture *tex1, IT
mat.enableTexAddrMode(false); mat.enableTexAddrMode(false);
break; break;
case EnvBumpMap: case EnvBumpMap:
if (drv.isTextureAddrModeSupported(CMaterial::OffsetTexture)) if (drv.supportTextureAddrMode(CMaterial::OffsetTexture))
{ {
mat.setTexture(0, tex2); mat.setTexture(0, tex2);
mat.setTexture(1, tex1); mat.setTexture(1, tex1);
@ -1113,7 +1113,7 @@ void CPSMultiTexturedParticle::enumTexs(std::vector<NLMISC::CSmartPtr<ITexture>
NL_PS_FUNC(CPSMultiTexturedParticle_enumTexs) NL_PS_FUNC(CPSMultiTexturedParticle_enumTexs)
if (_MainOp == EnvBumpMap && !_ForceBasicCaps) if (_MainOp == EnvBumpMap && !_ForceBasicCaps)
{ {
if (drv.isTextureAddrModeSupported(CMaterial::OffsetTexture) || drv.supportEMBM()) if (drv.supportTextureAddrMode(CMaterial::OffsetTexture) || drv.supportEMBM())
{ {
if (_Texture2) dest.push_back(_Texture2); if (_Texture2) dest.push_back(_Texture2);
} }
@ -1132,7 +1132,7 @@ bool CPSMultiTexturedParticle::isAlternateTextureUsed(IDriver &driver) const
NL_PS_FUNC(CPSMultiTexturedParticle_isAlternateTextureUsed) NL_PS_FUNC(CPSMultiTexturedParticle_isAlternateTextureUsed)
if (!isTouched() && areBasicCapsForcedLocal() == areBasicCapsForced()) return (_MultiTexState & AlternateTextureUsed) != 0; if (!isTouched() && areBasicCapsForcedLocal() == areBasicCapsForced()) return (_MultiTexState & AlternateTextureUsed) != 0;
if (_MainOp != EnvBumpMap) return false; if (_MainOp != EnvBumpMap) return false;
return _ForceBasicCaps || (!driver.isTextureAddrModeSupported(CMaterial::OffsetTexture) && !driver.supportEMBM()); return _ForceBasicCaps || (!driver.supportTextureAddrMode(CMaterial::OffsetTexture) && !driver.supportEMBM());
} }
} // NL3D } // NL3D

View file

@ -191,6 +191,8 @@ CScene::CScene(bool bSmallScene) : LightTrav(bSmallScene)
_WaterEnvMap = NULL; _WaterEnvMap = NULL;
_GlobalSystemTime= 0.0; _GlobalSystemTime= 0.0;
_RequestParticlesAnimate = false;
} }
// *************************************************************************** // ***************************************************************************
void CScene::release() void CScene::release()
@ -377,6 +379,12 @@ void CScene::endPartRender()
// Reset profiling // Reset profiling
_NextRenderProfile= false; _NextRenderProfile= false;
IDriver *drv = getDriver();
drv->activeVertexProgram(NULL);
drv->activePixelProgram(NULL);
// Ensure nothing animates on subsequent renders
_EllapsedTime = 0.f;
/* /*
uint64 total = PSStatsRegisterPSModelObserver + uint64 total = PSStatsRegisterPSModelObserver +
@ -614,7 +622,11 @@ void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass)
// loadBalance // loadBalance
LoadBalancingTrav.traverse(); 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 // Light
LightTrav.traverse(); LightTrav.traverse();
} }
@ -860,6 +872,9 @@ void CScene::animate( TGlobalAnimationTime atTime )
// Rendered part are invalidate // Rendered part are invalidate
_RenderedPart = UScene::RenderNothing; _RenderedPart = UScene::RenderNothing;
// Particles are animated later due to dependencies
_RequestParticlesAnimate = true;
} }
@ -1561,6 +1576,7 @@ void CScene::renderOcclusionTestMeshs()
nlassert(RenderTrav.getDriver()); nlassert(RenderTrav.getDriver());
RenderTrav.getDriver()->setupViewport(RenderTrav.getViewport()); RenderTrav.getDriver()->setupViewport(RenderTrav.getViewport());
RenderTrav.getDriver()->activeVertexProgram(NULL); RenderTrav.getDriver()->activeVertexProgram(NULL);
RenderTrav.getDriver()->activePixelProgram(NULL);
IDriver::TPolygonMode oldPolygonMode = RenderTrav.getDriver()->getPolygonMode(); IDriver::TPolygonMode oldPolygonMode = RenderTrav.getDriver()->getPolygonMode();
CMaterial m; CMaterial m;
m.initUnlit(); m.initUnlit();

View file

@ -244,11 +244,12 @@ void CShadowMapManager::addShadowReceiver(CTransform *model)
void CShadowMapManager::renderGenerate(CScene *scene) void CShadowMapManager::renderGenerate(CScene *scene)
{ {
H_AUTO( NL3D_ShadowManager_Generate ); H_AUTO( NL3D_ShadowManager_Generate );
// Each frame, do a small garbage collector for unused free textures. // Each frame, do a small garbage collector for unused free textures.
garbageShadowTextures(scene); garbageShadowTextures(scene);
IDriver *driverForShadowGeneration= scene->getRenderTrav().getAuxDriver(); IDriver *driverForShadowGeneration= scene->getRenderTrav().getAuxDriver();
CSmartPtr<NL3D::ITexture> previousRenderTarget = driverForShadowGeneration->getRenderTarget();
// Init // Init
// ******** // ********
@ -488,7 +489,7 @@ void CShadowMapManager::renderGenerate(CScene *scene)
} }
// Set default render target // Set default render target
driverForShadowGeneration->setRenderTarget (NULL); driverForShadowGeneration->setRenderTarget (previousRenderTarget);
// Allow Writing on all. // Allow Writing on all.
driverForShadowGeneration->setColorMask(true, true, true, true); driverForShadowGeneration->setColorMask(true, true, true, true);

View file

@ -0,0 +1,410 @@
/**
* \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";
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);
NL3D::IDriver *drvInternal = (static_cast<CDriverUser *>(driver))->getDriver();
/*if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures())
{
nldebug("VR: fp40");
m_PixelProgram = new CPixelProgram(a_fp40);
}
else*/ if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures())
{
nldebug("VR: arbfp1");
m_PixelProgram = new CPixelProgram(a_arbfp1);
}
/*else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0))
{
nldebug("VR: ps_2_0");
m_PixelProgram = new CPixelProgram(a_ps_2_0);
}*/
if (m_PixelProgram)
{
m_Driver = driver;
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::PostProcessing);
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 */

View file

@ -0,0 +1,108 @@
/**
* \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_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
#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 */

View 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 */

View file

@ -0,0 +1,743 @@
/**
* \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;
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;
}
void CStereoOVR::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.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::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 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->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, 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->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 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 */

View file

@ -0,0 +1,202 @@
/************************************************************************************
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 cTex0 : 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 cTex0 : 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 cTex0 : 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";
}

View file

@ -98,7 +98,7 @@ void CVegetableVBAllocator::updateDriver(IDriver *driver)
_VBHardOk= false; _VBHardOk= false;
// Driver must support VP. // Driver must support VP.
nlassert(_Driver->isVertexProgramSupported()); nlassert(_Driver->supportVertexProgram());
// must reallocate the VertexBuffer. // must reallocate the VertexBuffer.
if( _NumVerticesAllocated>0 ) if( _NumVerticesAllocated>0 )

View file

@ -61,7 +61,7 @@ void CWaterModel::setupVertexBuffer(CVertexBuffer &vb, uint numWantedVertices, I
vb.setNumVertices(0); vb.setNumVertices(0);
vb.setName("Water"); vb.setName("Water");
vb.setPreferredMemory(CVertexBuffer::AGPPreferred, false); vb.setPreferredMemory(CVertexBuffer::AGPPreferred, false);
if (drv->isWaterShaderSupported()) if (drv->supportWaterShader())
{ {
vb.setVertexFormat(CVertexBuffer::PositionFlag); vb.setVertexFormat(CVertexBuffer::PositionFlag);
} }
@ -377,7 +377,7 @@ void CWaterModel::traverseRender()
#ifndef FORCE_SIMPLE_WATER_RENDER #ifndef FORCE_SIMPLE_WATER_RENDER
if (!drv->isWaterShaderSupported()) if (!drv->supportWaterShader())
#endif #endif
{ {
doSimpleRender(drv); doSimpleRender(drv);
@ -1363,7 +1363,7 @@ uint CWaterModel::getNumWantedVertices()
uint CWaterModel::fillVB(void *datas, uint startTri, IDriver &drv) uint CWaterModel::fillVB(void *datas, uint startTri, IDriver &drv)
{ {
H_AUTO( NL3D_Water_Render ); H_AUTO( NL3D_Water_Render );
if (drv.isWaterShaderSupported()) if (drv.supportWaterShader())
{ {
return fillVBHard(datas, startTri); return fillVBHard(datas, startTri);
} }
@ -1657,7 +1657,7 @@ void CWaterModel::traverseRender()
drv->setupModelMatrix(modelMat); drv->setupModelMatrix(modelMat);
bool isAbove = obsPos.z > getWorldMatrix().getPos().z; bool isAbove = obsPos.z > getWorldMatrix().getPos().z;
CVertexBuffer &vb = renderTrav.Scene->getWaterVB(); CVertexBuffer &vb = renderTrav.Scene->getWaterVB();
if (drv->isWaterShaderSupported()) if (drv->supportWaterShader())
{ {
setupMaterialNVertexShader(drv, shape, obsPos, isAbove, zHeight); setupMaterialNVertexShader(drv, shape, obsPos, isAbove, zHeight);
nlassert(vb.getNumVertices() > 0); nlassert(vb.getNumVertices() > 0);

View file

@ -372,7 +372,7 @@ void CWaterShape::flushTextures (IDriver &driver, uint selectedTexture)
/* /*
if ( if (
(driver.supportTextureShaders() && driver.isTextureAddrModeSupported(CMaterial::OffsetTexture)) (driver.supportTextureShaders() && driver.supportTextureAddrMode(CMaterial::OffsetTexture))
|| driver.supportEMBM() || driver.supportEMBM()
) )
{ {

View 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 */

View 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 */

View file

@ -302,6 +302,10 @@ CClientConfig::CClientConfig()
Contrast = 0.f; // Default Monitor Contrast. Contrast = 0.f; // Default Monitor Contrast.
Luminosity = 0.f; // Default Monitor Luminosity. Luminosity = 0.f; // Default Monitor Luminosity.
Gamma = 0.f; // Default Monitor Gamma. Gamma = 0.f; // Default Monitor Gamma.
VREnable = false;
VRDisplayDevice = "Auto";
VRDisplayDeviceId = "";
Local = false; // Default is Net Mode. Local = false; // Default is Net Mode.
FSHost = ""; // Default Host. FSHost = ""; // Default Host.
@ -847,6 +851,9 @@ void CClientConfig::setValues()
else else
cfgWarning ("Default value used for 'Driver3D' !!!"); cfgWarning ("Default value used for 'Driver3D' !!!");
READ_BOOL_FV(VREnable)
READ_STRING_FV(VRDisplayDevice)
READ_STRING_FV(VRDisplayDeviceId)
//////////// ////////////
// INPUTS // // INPUTS //

View file

@ -146,6 +146,11 @@ struct CClientConfig
/// Monitor Gamma [-1 ~ 1], default 0 /// Monitor Gamma [-1 ~ 1], default 0
float Gamma; float Gamma;
// VR
bool VREnable;
std::string VRDisplayDevice;
std::string VRDisplayDeviceId;
/// Client in Local mode or not. /// Client in Local mode or not.
bool Local; bool Local;
/// Host. /// Host.

View file

@ -560,7 +560,7 @@ void CDecalRenderList::renderAllDecals()
NL3D::IDriver *drvInternal = ((CDriverUser *) Driver)->getDriver(); NL3D::IDriver *drvInternal = ((CDriverUser *) Driver)->getDriver();
// //
static volatile bool forceNoVertexProgram = false; static volatile bool forceNoVertexProgram = false;
if (drvInternal->isVertexProgramSupported() && !forceNoVertexProgram) if (drvInternal->supportVertexProgram() && !forceNoVertexProgram)
{ {
//drvInternal->setConstantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity); //drvInternal->setConstantMatrix(0, NL3D::IDriver::ModelViewProjection, NL3D::IDriver::Identity);
drvInternal->setConstant(7, _DistScale, _DistBias, 0.f, 1.f); drvInternal->setConstant(7, _DistScale, _DistBias, 0.f, 1.f);

View file

@ -26,6 +26,8 @@ using namespace NLMISC;
// *************************************************************************** // ***************************************************************************
// Main System // Main System
NL3D::UDriver *Driver = 0; // The main 3D Driver 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 CSoundManager *SoundMngr = 0; // the sound manager
NL3D::UMaterial GenericMat; // Generic Material NL3D::UMaterial GenericMat; // Generic Material
NL3D::UTextContext *TextContext = 0; // Context for all the text in the client. NL3D::UTextContext *TextContext = 0; // Context for all the text in the client.

View file

@ -40,6 +40,8 @@ namespace NL3D
class UMaterial; class UMaterial;
class UTextContext; class UTextContext;
class UWaterEnvMap; class UWaterEnvMap;
class IStereoDisplay;
class IStereoHMD;
} }
class CEntityAnimationManager; class CEntityAnimationManager;
@ -77,6 +79,8 @@ const float ExtraZoneLoadingVision = 100.f;
// *************************************************************************** // ***************************************************************************
// Main System // Main System
extern NL3D::UDriver *Driver; // The main 3D Driver 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 CSoundManager *SoundMngr; // the sound manager
extern NL3D::UMaterial GenericMat; // Generic Material extern NL3D::UMaterial GenericMat; // Generic Material
extern NL3D::UTextContext *TextContext; // Context for all the text in the client. extern NL3D::UTextContext *TextContext; // Context for all the text in the client.

View file

@ -39,6 +39,7 @@
#include "nel/3d/u_driver.h" #include "nel/3d/u_driver.h"
#include "nel/3d/u_text_context.h" #include "nel/3d/u_text_context.h"
#include "nel/3d/u_shape_bank.h" #include "nel/3d/u_shape_bank.h"
#include "nel/3d/stereo_hmd.h"
// Net. // Net.
#include "nel/net/email.h" #include "nel/net/email.h"
// Ligo. // Ligo.
@ -46,6 +47,7 @@
// Std. // Std.
#include <fstream> #include <fstream>
#include <sstream>
// Game Share // Game Share
#include "game_share/ryzom_version.h" #include "game_share/ryzom_version.h"
// Client // Client
@ -792,6 +794,59 @@ void prelogInit()
// Check driver version // Check driver version
checkDriverVersion(); 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). // Create the driver (most important part of the client).
nmsg = "Creating 3d driver..."; nmsg = "Creating 3d driver...";
ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) ); ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
@ -860,6 +915,11 @@ void prelogInit()
Driver->setSwapVBLInterval(1); Driver->setSwapVBLInterval(1);
else else
Driver->setSwapVBLInterval(0); Driver->setSwapVBLInterval(0);
if (StereoDisplay)
{
// override mode TODO
}
// Set the mode of the window. // Set the mode of the window.
if (!Driver->setDisplay (mode, false)) if (!Driver->setDisplay (mode, false))
@ -1102,6 +1162,12 @@ void prelogInit()
// init bloom effect // init bloom effect
CBloomEffect::getInstance().init(driver != UDriver::Direct3d); 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); nlinfo ("PROFILE: %d seconds for prelogInit", (uint32)(ryzomGetLocalTime ()-initStart)/1000);

View file

@ -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 cbScene = setupCameraForScreenshot(*Scene, left, right, top, bottom, screenShotWidth, screenShotHeight);
CCameraBackup cbCanopy = setupCameraForScreenshot(*SceneRoot, 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 // 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(*Scene, cbScene);
restoreCamera(*SceneRoot, cbCanopy); restoreCamera(*SceneRoot, cbCanopy);
commitCamera();
} }
// *************************************************************************** // ***************************************************************************

View file

@ -95,11 +95,11 @@ public:
private: 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. // 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. // 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 // The eighth bit will be written with a 0 during next render to mark stencil buffer parts which will
// support Shadow Volume algorithm. // support Shadow Volume algorithm.

File diff suppressed because it is too large Load diff

View file

@ -29,9 +29,13 @@ const uint NUM_MISSION_OPTIONS = 8;
bool mainLoop(); bool mainLoop();
// render all // render all
void renderAll(bool forceFullDetail = false); void renderScene();
void renderScene(bool forceFullDetail, bool bloom);
void setDefaultChatWindow(CChatWindow *defaultChatWindow); void setDefaultChatWindow(CChatWindow *defaultChatWindow);
// Commit sky scene camera for rendering
void commitCamera();
void updateDayNightCycleHour(); void updateDayNightCycleHour();

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View file

@ -0,0 +1,36 @@
// 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_PROFILING_H
#define CL_PROFILING_H
#include <nel/misc/types_nl.h>
extern bool Profiling; // Are we in Profile mode?
extern uint ProfileNumFrame;
extern bool WantProfiling;
extern bool ProfilingVBLock;
extern bool WantProfilingVBLock;
/// Test Profiling and run?
void testLaunchProfile();
/// Test ProfilingVBLock and run?
void testLaunchProfileVBLock();
#endif // CL_PROFILING_H
/* end of file */

View file

@ -35,6 +35,7 @@
#include "nel/3d/u_scene.h" #include "nel/3d/u_scene.h"
#include "nel/3d/u_visual_collision_manager.h" #include "nel/3d/u_visual_collision_manager.h"
#include "nel/3d/u_shape_bank.h" #include "nel/3d/u_shape_bank.h"
#include "nel/3d/stereo_hmd.h"
// Client // Client
#include "global.h" #include "global.h"
#include "release.h" #include "release.h"
@ -559,6 +560,15 @@ void release()
CEntityAnimationManager::delInstance(); CEntityAnimationManager::delInstance();
EAM= NULL; EAM= NULL;
nldebug("VR [C]: VR Shutting down");
if (StereoDisplay)
{
delete StereoDisplay;
StereoDisplay = NULL;
StereoHMD = NULL;
}
IStereoDisplay::releaseAllLibraries();
// Delete the driver. // Delete the driver.
if(Driver) if(Driver)
{ {

View file

@ -183,7 +183,6 @@ CVector CView::currentViewPos() const
//----------------------------------------------- //-----------------------------------------------
// currentView : // currentView :
// Set the user position.
//----------------------------------------------- //-----------------------------------------------
CVector CView::currentView() const CVector CView::currentView() const
{ {
@ -200,6 +199,14 @@ CVector CView::currentView() const
return _View; return _View;
}// currentView // }// currentView //
NLMISC::CQuat CView::currentViewQuat() const
{
CMatrix mat;
mat.setRot(CVector::I, currentView(), CVector::K);
mat.normalize(CMatrix::YZX);
return mat.getRot();
}
//----------------------------------------------- //-----------------------------------------------
// currentCameraTarget : // currentCameraTarget :
//----------------------------------------------- //-----------------------------------------------

View file

@ -115,6 +115,8 @@ public:
CVector currentViewPos() const; CVector currentViewPos() const;
// Return the current view (rear or normal) // Return the current view (rear or normal)
CVector currentView() const; CVector currentView() const;
// Return the current view as a quaternion
NLMISC::CQuat currentViewQuat() const;
// Return the current Camera Target (for 3rd person only. 1st person: return currentViewPos()) // Return the current Camera Target (for 3rd person only. 1st person: return currentViewPos())
CVector currentCameraTarget() const; CVector currentCameraTarget() const;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,54 @@
/************************************************************************************
Filename : pp_oculus_vr.cg
Content : Barrel fragment program ported from Oculus SDK Samples to Cg
Created : July 01, 2013
Modified by : Jan Boon (Kaetemi)
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
void pp_oculus_vr(
// Per fragment parameters
float2 texCoord : TEXCOORD0,
// Fragment program constants
uniform float2 cLensCenter,
uniform float2 cScreenCenter,
uniform float2 cScale,
uniform float2 cScaleIn,
uniform float4 cHmdWarpParam,
uniform sampler2D cTex0 : TEX0,
// Output color
out float4 oCol : COLOR)
{
float2 theta = (texCoord - cLensCenter) * cScaleIn; // Scales to [-1, 1]
float rSq = theta.x * theta.x + theta.y * theta.y;
float2 theta1 = theta * (cHmdWarpParam.x + cHmdWarpParam.y * rSq +
cHmdWarpParam.z * rSq * rSq + cHmdWarpParam.w * rSq * rSq * rSq);
float2 tc = cLensCenter + cScale * theta1;
if (!all(equal(clamp(tc, cScreenCenter-float2(0.25,0.5), cScreenCenter+float2(0.25,0.5)), tc)))
{
oCol = float4(0, 0, 0, 0);
}
else
{
oCol = tex2D(cTex0, tc);
}
}

View file

@ -0,0 +1,25 @@
void pp_stereo_debug(
// Per fragment parameters
float2 texCoord : TEXCOORD0,
// Fragment program constants
uniform sampler2D cTex0 : TEX0,
uniform sampler2D cTex1 : TEX1,
// Output color
out float4 oCol : COLOR)
{
float4 t1 = tex2D(cTex0, texCoord);
float4 t2 = tex2D(cTex1, texCoord);
if (!any(t1 - t2))
{
oCol = (t1 * 0.5) + (t2 * 0.5);
oCol.g = 0.5 + (oCol.g * 0.5);
}
else
{
oCol = (t1 * 0.5) + (t2 * 0.5);
oCol.r = 0.5 + (oCol.r * 0.5);
}
}

View file

@ -0,0 +1,13 @@
void pp_test(
// Per fragment parameters
float2 texCoord : TEXCOORD0,
// Fragment program constants
uniform sampler2D cTex0 : TEX0,
// Output color
out float4 oCol : COLOR)
{
oCol.rba = float3(1.0, 0.0, 1.0);
oCol.g = tex2D(cTex0, texCoord).g;
}

24
code/snowballs2/bin/snowballs_client_default.cfg Normal file → Executable file
View file

@ -47,17 +47,26 @@ FpsSmoothing = 64;
OpenGL = 1; OpenGL = 1;
// Resolution of the screen // Resolution of the screen
ScreenWidth = 800; ScreenWidth = 1280;
ScreenHeight = 600; ScreenHeight = 800;
ScreenDepth = 32; ScreenDepth = 32;
// If 1, run in fullscreen mode, 0 for windowed // If 1, run in fullscreen mode, 0 for windowed
ScreenFull = 0; ScreenFull = 1;
// Start position of the player (the z is always 0) // Start position of the player (the z is always 0)
StartPoint = { 1840.0, -970.0, 0.0 }; StartPoint = { 1840.0, -970.0, 0.0 };
//////////////////////////////////////////////////////////////////////////////
// HMD Variables /////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
HMDEnable = 1;
HMDDeviceId = 0;
HMDDevice = "Auto";
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Sound Variables /////////////////////////////////////////////////////////// // Sound Variables ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -256,6 +265,15 @@ RetrieverBankName = "snowballs.rbank";
GlobalRetrieverName = "snowballs.gr"; GlobalRetrieverName = "snowballs.gr";
//////////////////////////////////////////////////////////////////////////////
// Bloom Variables ///////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
SquareBloom = 1;
DensityBloom = 128;
EnableBloom = 1;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Compass interface Variables /////////////////////////////////////////////// // Compass interface Variables ///////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View file

@ -97,7 +97,7 @@ Anim AnimIdArray[][2] =
void computeAnimation (CEntity &entity, EAnim anim) void computeAnimation (CEntity &entity, EAnim anim)
{ {
// Get the current time // Get the current time
double currentTime = double (CTime::getLocalTime ())/1000.0f; double currentTime = AnimationTime;
// nlinfo ("%d playing animation", anim); // nlinfo ("%d playing animation", anim);
// nlinfo ("%d playing animation %s ct%f st%f et%f", anim, AnimIdArray[anim][0].Name, currentTime, AnimIdArray[anim][0].Animation->getBeginTime (), AnimIdArray[anim][0].Animation->getEndTime ()); // nlinfo ("%d playing animation %s ct%f st%f et%f", anim, AnimIdArray[anim][0].Name, currentTime, AnimIdArray[anim][0].Animation->getBeginTime (), AnimIdArray[anim][0].Animation->getEndTime ());
@ -153,7 +153,7 @@ void playAnimation (CEntity &entity, EAnim anim, bool force)
// nlinfo ("playAnimation() %d", anim); // nlinfo ("playAnimation() %d", anim);
// Get the current time // Get the current time
CAnimationTime currentTime = CAnimationTime(CTime::getLocalTime ())/1000.0f; CAnimationTime currentTime = AnimationTime;
// Can't do animation without skeleton // Can't do animation without skeleton
if (entity.Skeleton.empty()) if (entity.Skeleton.empty())
@ -224,7 +224,7 @@ void initAnimation()
void updateAnimation() void updateAnimation()
{ {
// Get the current time // Get the current time
CAnimationTime currentTime = CAnimationTime(CTime::getLocalTime ())/1000.0f; CAnimationTime currentTime = AnimationTime;
for (EIT eit = Entities.begin (); eit != Entities.end (); eit++) for (EIT eit = Entities.begin (); eit != Entities.end (); eit++)
{ {
@ -270,7 +270,7 @@ void updateAnimation()
} }
// compute new animation position depending of the current time // compute new animation position depending of the current time
PlayListManager->animate (double(CTime::getLocalTime ())/1000.0f); PlayListManager->animate (AnimationTime);
} }
void releaseAnimation() void releaseAnimation()

View file

@ -21,6 +21,7 @@
#include <nel/misc/types_nl.h> #include <nel/misc/types_nl.h>
#include <cmath> #include <cmath>
#include <sstream>
#include <nel/misc/vectord.h> #include <nel/misc/vectord.h>
#include <nel/misc/config_file.h> #include <nel/misc/config_file.h>
#include <nel/3d/u_camera.h> #include <nel/3d/u_camera.h>
@ -33,6 +34,8 @@
#include <nel/3d/u_cloud_scape.h> #include <nel/3d/u_cloud_scape.h>
#include <nel/3d/viewport.h> #include <nel/3d/viewport.h>
#include <nel/3d/stereo_hmd.h>
#include "snowballs_client.h" #include "snowballs_client.h"
#include "entities.h" #include "entities.h"
#include "mouse_listener.h" #include "mouse_listener.h"
@ -61,22 +64,75 @@ UVisualCollisionEntity *CamCollisionEntity = NULL;
static UInstance Snow = NULL; static UInstance Snow = NULL;
// The sky 3D objects // The sky 3D objects
static UScene *SkyScene = NULL; UScene *SkyScene = NULL;
static UCamera SkyCamera = NULL; UCamera SkyCamera = NULL;
static UInstance Sky = NULL; static UInstance Sky = NULL;
static UCloudScape *Clouds = NULL; static UCloudScape *Clouds = NULL;
IStereoDisplay *StereoDisplay = NULL;
IStereoHMD *StereoHMD = NULL;
// //
// Functions // Functions
// //
void initCamera() void initCamera()
{ {
if (ConfigFile->getVar("HMDEnable").asBool())
{
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("Stereo Display: %s", name.str().c_str());
}
CStereoDeviceInfo *deviceInfo = NULL;
std::string hmdDeviceCfg = ConfigFile->getVar("HMDDevice").asString();
if (hmdDeviceCfg == std::string("Auto")
&& devices.begin() != devices.end())
{
deviceInfo = &devices[0];
}
else
{
std::string hmdDeviceId = ConfigFile->getVar("HMDDeviceId").asString();
for (std::vector<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() == hmdDeviceCfg)
deviceInfo = &(*it);
if (hmdDeviceId == it->Serial)
break;
}
}
if (deviceInfo)
{
nlinfo("Create VR stereo display device");
StereoDisplay = IStereoDisplay::createDevice(*deviceInfo);
if (StereoDisplay)
{
if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD)
{
nlinfo("Stereo display device is a HMD");
StereoHMD = static_cast<IStereoHMD *>(StereoDisplay);
StereoHMD->setScale(3.0f); // snowballs is about 4 units per meter
}
StereoDisplay->setDriver(Driver); // move after driver creation, move stereodisplay before driver creation
}
}
}
IStereoDisplay::releaseUnusedLibraries();
// Set up directly the camera // Set up directly the camera
Camera = Scene->getCam(); Camera = Scene->getCam();
Camera.setTransformMode (UTransformable::DirectMatrix); Camera.setTransformMode (UTransformable::DirectMatrix);
Camera.setPerspective ((float)Pi/2.f, 1.33f, 0.1f, 1000); Camera.setPerspective((float)Pi/2.f,
ConfigFile->getVar("ScreenWidth").asFloat() / ConfigFile->getVar("ScreenHeight").asFloat(),
0.1f, 1000.f);
Camera.lookAt (CVector(ConfigFile->getVar("StartPoint").asFloat(0), Camera.lookAt (CVector(ConfigFile->getVar("StartPoint").asFloat(0),
ConfigFile->getVar("StartPoint").asFloat(1), ConfigFile->getVar("StartPoint").asFloat(1),
ConfigFile->getVar("StartPoint").asFloat(2)), ConfigFile->getVar("StartPoint").asFloat(2)),
@ -114,10 +170,30 @@ void releaseCamera()
Driver->deleteScene(SkyScene); Driver->deleteScene(SkyScene);
Scene->deleteInstance(Snow); Scene->deleteInstance(Snow);
VisualCollisionManager->deleteEntity(CamCollisionEntity); VisualCollisionManager->deleteEntity(CamCollisionEntity);
if (StereoHMD)
{
delete StereoHMD;
StereoHMD = NULL;
StereoDisplay = NULL;
}
delete StereoDisplay;
StereoDisplay = NULL;
IStereoDisplay::releaseAllLibraries();
} }
void updateCamera() void updateCamera()
{ {
if (StereoHMD)
{
NLMISC::CQuat hmdOrient = StereoHMD->getOrientation();
NLMISC::CMatrix camMatrix = Camera.getMatrix();
NLMISC::CMatrix hmdMatrix;
hmdMatrix.setRot(hmdOrient);
NLMISC::CMatrix posMatrix; // minimal head modeling, will be changed in the future
posMatrix.translate(StereoHMD->getEyePosition());
Camera.setMatrix((camMatrix * hmdMatrix) * posMatrix);
}
// Set the new position of the snow emitter // Set the new position of the snow emitter
CMatrix mat = CMatrix::Identity; CMatrix mat = CMatrix::Identity;
mat.setPos (Camera.getMatrix().getPos()/*+CVector (0.0f, 0.0f, -10.0f)*/); mat.setPos (Camera.getMatrix().getPos()/*+CVector (0.0f, 0.0f, -10.0f)*/);
@ -143,7 +219,8 @@ void releaseSky()
// -- -- random note: update and render makes more sense than animate and update // -- -- random note: update and render makes more sense than animate and update
void animateSky(double dt) void animateSky(double dt)
{ {
Clouds->anim(dt); if (!StereoHMD) Clouds->anim(dt);
SkyScene->animate(AnimationTime);
} }
// this is actually render // this is actually render
@ -156,12 +233,12 @@ void updateSky()
skyCameraMatrix.setPos(CVector::Null); skyCameraMatrix.setPos(CVector::Null);
SkyCamera.setMatrix(skyCameraMatrix); SkyCamera.setMatrix(skyCameraMatrix);
SkyScene->animate(AnimationTime);
SkyScene->render(); SkyScene->render();
// Must clear ZBuffer For incoming rendering. // Must clear ZBuffer For incoming rendering.
Driver->clearZBuffer(); Driver->clearZBuffer();
Clouds->render(); if (!StereoHMD) // Cloudscape not supported (fix Viewport please)
Clouds->render();
} }
} /* namespace SBCLIENT */ } /* namespace SBCLIENT */

View file

@ -30,6 +30,7 @@
namespace NL3D namespace NL3D
{ {
class UVisualCollisionEntity; class UVisualCollisionEntity;
class CStereoOVR;
}; };
namespace SBCLIENT { namespace SBCLIENT {
@ -39,7 +40,9 @@ namespace SBCLIENT {
// //
extern NL3D::UCamera Camera; extern NL3D::UCamera Camera;
extern NL3D::UCamera SkyCamera;
extern NL3D::UVisualCollisionEntity *CamCollisionEntity; extern NL3D::UVisualCollisionEntity *CamCollisionEntity;
extern NL3D::UScene *SkyScene;
// //
// External functions // External functions

View file

@ -35,11 +35,20 @@
#include <nel/3d/u_3d_mouse_listener.h> #include <nel/3d/u_3d_mouse_listener.h>
#include <nel/3d/u_material.h> #include <nel/3d/u_material.h>
#include <nel/3d/u_landscape.h> #include <nel/3d/u_landscape.h>
#include <nel/3d/stereo_hmd.h>
#include "network.h" #include "network.h"
#include "snowballs_client.h" #include "snowballs_client.h"
#include "interface.h" #include "interface.h"
#if SBCLIENT_DEV_PIXEL_PROGRAM
#include <nel/3d/driver_user.h>
#include <nel/3d/driver.h>
#include <nel/3d/pixel_program.h>
#include <nel/3d/material.h>
#include <nel/3d/u_texture.h>
#endif
// //
// Namespaces // Namespaces
// //
@ -237,6 +246,13 @@ void cbUpdateCommands (CConfigFile::CVar &var)
else nlwarning ("Unknown variable update %s", var.Name.c_str()); else nlwarning ("Unknown variable update %s", var.Name.c_str());
} }
#if SBCLIENT_DEV_PIXEL_PROGRAM
namespace {
CPixelProgram *a_DevPixelProgram = NULL;
UTextureFile *a_NelLogo;
}
#endif
void initCommands() void initCommands()
{ {
// Add the keyboard listener in the event server // Add the keyboard listener in the event server
@ -278,6 +294,79 @@ void initCommands()
CommandsMaterial.initUnlit(); CommandsMaterial.initUnlit();
CommandsMaterial.setBlendFunc(UMaterial::srcalpha, UMaterial::invsrcalpha); CommandsMaterial.setBlendFunc(UMaterial::srcalpha, UMaterial::invsrcalpha);
CommandsMaterial.setBlend(true); CommandsMaterial.setBlend(true);
#if SBCLIENT_DEV_PIXEL_PROGRAM
CommandsMaterial.getObjectPtr()->setShader(NL3D::CMaterial::PostProcessing);
a_NelLogo = Driver->createTextureFile("nel128.tga");
CommandsMaterial.setTexture(dynamic_cast<NL3D::UTexture *>(a_NelLogo));
static const char *program_arbfp1 =
"!!ARBfp1.0\n"
"PARAM c[1] = { { 1, 0 } };\n"
"MOV result.color.xzw, c[0].xyyx;\n"
"TEX result.color.y, fragment.texcoord[0], texture[0], 2D;\n"
"END\n";
static const char *program_fp40 =
"!!ARBfp1.0\n"
"OPTION NV_fragment_program2;\n"
"PARAM c[1] = { { 1, 0 } };\n"
"TEMP RC;\n"
"TEMP HC;\n"
"OUTPUT oCol = result.color;\n"
"MOVR oCol.xzw, c[0].xyyx;\n"
"TEX oCol.y, fragment.texcoord[0], texture[0], 2D;\n"
"END\n";
static const char *program_ps_1_1 =
"ps.1.1\n"
"def c0, 0.000000, 0.000000, 1.000000, 0.000000\n"
"def c1, 1.000000, 0.000000, 0.000000, 0.000000\n"
"def c2, 0.000000, 1.000000, 0.000000, 0.000000\n"
"tex t0\n"
"mad r0.rgb, c2, t0, c1\n"
"mov r0.a, c0.b\n";
static const char *program_ps_2_0 =
"ps_2_0\n"
"dcl_2d s0\n"
"def c0, 1.00000000, 0.00000000, 0, 0\n"
"dcl t0.xy\n"
"texld r0, t0, s0\n"
"mov r0.z, c0.y\n"
"mov r0.xw, c0.x\n"
"mov oC0, r0\n";
static const char *program_ps_3_0 =
"ps_3_0\n"
"dcl_2d s0\n"
"def c0, 1.00000000, 0.00000000, 0, 0\n"
"dcl_texcoord0 v0.xy\n"
"mov oC0.xzw, c0.xyyx\n"
"texld oC0.y, v0, s0\n";
NL3D::IDriver *d = dynamic_cast<NL3D::CDriverUser *>(Driver)->getDriver();
if (d->supportPixelProgram(CPixelProgram::fp40))
{
nldebug("fp40");
a_DevPixelProgram = new CPixelProgram(program_fp40);
}
else if (d->supportPixelProgram(CPixelProgram::arbfp1))
{
nldebug("arbfp1");
a_DevPixelProgram = new CPixelProgram(program_arbfp1);
}
/*else if (d->supportPixelProgram(CPixelProgram::ps_3_0))
{
nldebug("ps_3_0");
a_DevPixelProgram = new CPixelProgram(program_ps_3_0);
// Textures do not seem to work with ps_3_0...
}*/
else if (d->supportPixelProgram(CPixelProgram::ps_2_0))
{
nldebug("ps_2_0");
a_DevPixelProgram = new CPixelProgram(program_ps_2_0);
}
else if (d->supportPixelProgram(CPixelProgram::ps_1_1))
{
nldebug("ps_1_1");
a_DevPixelProgram = new CPixelProgram(program_ps_1_1);
}
#endif
} }
void updateCommands() void updateCommands()
@ -286,6 +375,9 @@ void updateCommands()
uint32 _width, _height; uint32 _width, _height;
Driver->getWindowSize(_width, _height); Driver->getWindowSize(_width, _height);
float width = (float)_width, height = (float)_height; float width = (float)_width, height = (float)_height;
NL3D::CViewport vp = Driver->getViewport();
width *= vp.getWidth();
height *= vp.getHeight();
float CommandsLineHeight = CommandsFontSize / height; float CommandsLineHeight = CommandsFontSize / height;
float CommandsBoxX = ((float)(sint32)(SBCLIENT::CommandsBoxX * width)) / width; float CommandsBoxX = ((float)(sint32)(SBCLIENT::CommandsBoxX * width)) / width;
float CommandsBoxWidth = ((float)(sint32)(SBCLIENT::CommandsBoxWidth * width)) / width; float CommandsBoxWidth = ((float)(sint32)(SBCLIENT::CommandsBoxWidth * width)) / width;
@ -293,16 +385,57 @@ void updateCommands()
float CommandsBoxHeight = ((float)(sint32)((CommandsNbLines + 1) * CommandsLineHeight * width)) / width; float CommandsBoxHeight = ((float)(sint32)((CommandsNbLines + 1) * CommandsLineHeight * width)) / width;
float CommandsBoxBorderX = ((float)(sint32)(SBCLIENT::CommandsBoxBorder * width)) / width; float CommandsBoxBorderX = ((float)(sint32)(SBCLIENT::CommandsBoxBorder * width)) / width;
float CommandsBoxBorderY = ((float)(sint32)(SBCLIENT::CommandsBoxBorder * height)) / height; float CommandsBoxBorderY = ((float)(sint32)(SBCLIENT::CommandsBoxBorder * height)) / height;
if (StereoHMD)
{
float xshift, yshift;
StereoHMD->getInterface2DShift(0, xshift, yshift, 4.f);
// snap to pixels
xshift = ((float)(sint32)(xshift * width)) / width;
yshift = ((float)(sint32)(yshift * height)) / height;
// adjust
CommandsBoxX += xshift;
CommandsBoxY += yshift;
}
// Display the background // Display the background
Driver->setMatrixMode2D11 (); Driver->setMatrixMode2D11 ();
#if SBCLIENT_DEV_PIXEL_PROGRAM
CommandsMaterial.setColor(CRGBA::Blue); // Test to check which shader is displaying.
#else
CommandsMaterial.setColor(CommandsBackColor); CommandsMaterial.setColor(CommandsBackColor);
#endif
float x0 = CommandsBoxX - CommandsBoxBorderX; float x0 = CommandsBoxX - CommandsBoxBorderX;
float y0 = CommandsBoxY - CommandsBoxBorderY; float y0 = CommandsBoxY - CommandsBoxBorderY;
float x1 = CommandsBoxX + CommandsBoxWidth + CommandsBoxBorderX; float x1 = CommandsBoxX + CommandsBoxWidth + CommandsBoxBorderX;
float y1 = CommandsBoxY + CommandsBoxHeight + CommandsBoxBorderY; float y1 = CommandsBoxY + CommandsBoxHeight + CommandsBoxBorderY;
#if SBCLIENT_DEV_PIXEL_PROGRAM
NL3D::IDriver *d = dynamic_cast<NL3D::CDriverUser *>(Driver)->getDriver();
d->activePixelProgram(a_DevPixelProgram);
bool fogEnabled = d->fogEnabled();
d->enableFog(false);
// Driver->drawQuad(CQuad(CVector(x0, y0, 0), CVector(x1, y0, 0), CVector(x1, y1, 0), CVector(x0, y1, 0)), CommandsMaterial);
CQuadUV quadUV;
quadUV.V0 = CVector(x0, y0, 0);
quadUV.V1 = CVector(x1, y0, 0);
quadUV.V2 = CVector(x1, y1, 0);
quadUV.V3 = CVector(x0, y1, 0);
quadUV.Uv0 = CUV(0, 1);
quadUV.Uv1 = CUV(1, 1);
quadUV.Uv2 = CUV(1, 0);
quadUV.Uv3 = CUV(0, 0);
Driver->drawQuad(quadUV, CommandsMaterial);
//Driver->drawBitmap(x0, y0, x1 - x0, y1 - y0, *a_NelLogo);
d->enableFog(fogEnabled);
d->activePixelProgram(NULL);
#else
Driver->drawQuad(CQuad(CVector(x0, y0, 0), CVector(x1, y0, 0), CVector(x1, y1, 0), CVector(x0, y1, 0)), CommandsMaterial); Driver->drawQuad(CQuad(CVector(x0, y0, 0), CVector(x1, y0, 0), CVector(x1, y1, 0), CVector(x0, y1, 0)), CommandsMaterial);
#endif
// Set the text context // Set the text context
TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setHotSpot (UTextContext::BottomLeft);
TextContext->setColor (CommandsFrontColor); TextContext->setColor (CommandsFrontColor);
@ -334,6 +467,10 @@ void clearCommands ()
void releaseCommands() void releaseCommands()
{ {
#if SBCLIENT_DEV_PIXEL_PROGRAM
delete a_DevPixelProgram;
a_DevPixelProgram = NULL;
#endif
// Remove the displayers // Remove the displayers
CommandsLog.removeDisplayer(&CommandsDisplayer); CommandsLog.removeDisplayer(&CommandsDisplayer);
#ifndef NL_RELEASE #ifndef NL_RELEASE

View file

@ -28,6 +28,7 @@
#include <nel/3d/u_driver.h> #include <nel/3d/u_driver.h>
#include <nel/3d/u_text_context.h> #include <nel/3d/u_text_context.h>
#include <nel/3d/u_texture.h> #include <nel/3d/u_texture.h>
#include <nel/3d/stereo_hmd.h>
#include "mouse_listener.h" #include "mouse_listener.h"
#include "camera.h" #include "camera.h"
@ -94,6 +95,13 @@ void updateCompass ()
{ {
float x = CompassPosX; float x = CompassPosX;
float y = CompassPosY; float y = CompassPosY;
if (StereoHMD)
{
float xshift, yshift;
StereoHMD->getInterface2DShift(0, xshift, yshift, 4.f);
x += xshift;
y += yshift;
}
float radius = CompassRadius; float radius = CompassRadius;
// tri // tri
@ -109,7 +117,8 @@ void updateCompass ()
quad.V2.set ( radius, radius, 0); quad.V2.set ( radius, radius, 0);
quad.V3.set (-radius, radius, 0); quad.V3.set (-radius, radius, 0);
Driver->setMatrixMode2D43 (); if (StereoHMD) Driver->setMatrixMode2D11();
else Driver->setMatrixMode2D43();
CMatrix mtx; CMatrix mtx;
@ -152,7 +161,7 @@ void updateCompass ()
Driver->setModelMatrix (mtx); Driver->setModelMatrix (mtx);
Driver->drawQuad (quad, CompassMaterial); Driver->drawQuad (quad, CompassMaterial);
x *= 3.0/4.0f; if (!StereoHMD) x *= 3.0/4.0f;
// Print position // Print position
TextContext->setHotSpot(UTextContext::MiddleTop); TextContext->setHotSpot(UTextContext::MiddleTop);

View file

@ -105,7 +105,7 @@ bool _TestCLS = false;
void CEntity::setState (TState state) void CEntity::setState (TState state)
{ {
State = state; State = state;
StateStartTime = CTime::getLocalTime (); StateStartTime = LocalTime;
} }
@ -376,7 +376,7 @@ void deleteAllEntities()
void stateAppear (CEntity &entity) void stateAppear (CEntity &entity)
{ {
// after 1 second, show the instance // after 1 second, show the instance
if (CTime::getLocalTime () > entity.StateStartTime + 1000) if (LocalTime > entity.StateStartTime + 1.0)
{ {
if (entity.Instance.getVisibility () != UTransform::Show) if (entity.Instance.getVisibility () != UTransform::Show)
entity.Instance.show (); entity.Instance.show ();
@ -384,7 +384,7 @@ void stateAppear (CEntity &entity)
// after 5 seconds, delete the particle system (if any) // after 5 seconds, delete the particle system (if any)
// and pass the entity into the Normal state // and pass the entity into the Normal state
if (CTime::getLocalTime () > entity.StateStartTime + 3000) if (LocalTime > entity.StateStartTime + 3.0)
{ {
if (!entity.Particule.empty()) if (!entity.Particule.empty())
{ {
@ -403,7 +403,7 @@ void stateAppear (CEntity &entity)
void stateDisappear (CEntity &entity) void stateDisappear (CEntity &entity)
{ {
// after 1 second, remove the mesh and all collision stuff // after 1 second, remove the mesh and all collision stuff
if (CTime::getLocalTime () > entity.StateStartTime + 1000) if (LocalTime > entity.StateStartTime + 1.0)
{ {
if (entity.Instance.getVisibility () != UTransform::Hide) if (entity.Instance.getVisibility () != UTransform::Hide)
{ {
@ -419,7 +419,7 @@ void stateDisappear (CEntity &entity)
} }
// after 5 seconds, remove the particle system and the entity entry // after 5 seconds, remove the particle system and the entity entry
if (CTime::getLocalTime () > entity.StateStartTime + 3000) if (LocalTime > entity.StateStartTime + 3.0)
{ {
deleteEntity (entity); deleteEntity (entity);
} }

View file

@ -108,7 +108,7 @@ public:
// The state of this entity // The state of this entity
TState State; TState State;
// The date of the beginning of this state // The date of the beginning of this state
NLMISC::TTime StateStartTime; NLMISC::TLocalTime StateStartTime;
// The type enum of the entity // The type enum of the entity
enum TType { Self, Other, Snowball }; enum TType { Self, Other, Snowball };

View file

@ -42,6 +42,14 @@ static bool _SkipAnimationOnce;
static NLMISC::TTime _TimeMs; static NLMISC::TTime _TimeMs;
static CValueSmootherTemplate<float> _FpsSmoother; static CValueSmootherTemplate<float> _FpsSmoother;
namespace
{
NLMISC::TLocalTime a_LocalTimeDelta;
NL3D::TGlobalAnimationTime a_AnimationTimeDelta;
} /* anonymous namespace */
static void cbFpsSmoothing(CConfigFile::CVar &var) static void cbFpsSmoothing(CConfigFile::CVar &var)
{ {
_FpsSmoother.init((uint)var.asInt()); _FpsSmoother.init((uint)var.asInt());
@ -53,8 +61,10 @@ void CGameTime::init()
_TimeMs = NLMISC::CTime::getLocalTime(); _TimeMs = NLMISC::CTime::getLocalTime();
LocalTime = ((TLocalTime)_TimeMs) / 1000.0; LocalTime = ((TLocalTime)_TimeMs) / 1000.0;
LocalTimeDelta = 0.0; LocalTimeDelta = 0.0;
a_LocalTimeDelta = 0.0;
AnimationTime = 0.0; AnimationTime = 0.0;
AnimationTimeDelta = 0.f; AnimationTimeDelta = 0.f;
a_AnimationTimeDelta = 0.0;
FramesPerSecond = 0.f; FramesPerSecond = 0.f;
FramesPerSecondSmooth = 0.f; FramesPerSecondSmooth = 0.f;
CConfiguration::setAndCallback("FpsSmoothing", cbFpsSmoothing); CConfiguration::setAndCallback("FpsSmoothing", cbFpsSmoothing);
@ -78,26 +88,24 @@ void CGameTime::updateTime()
// average of previous fps and this fps should be ok // average of previous fps and this fps should be ok
FramesPerSecond *= 3; FramesPerSecond *= 3;
LocalTimeDelta = 0.f; a_LocalTimeDelta = 0.f;
AnimationTimeDelta = 0.f; a_AnimationTimeDelta = 0.f;
} }
else else
{ {
FramesPerSecond = 1000.0f / (float)deltams; FramesPerSecond = 1000.0f / (float)deltams;
TLocalTime localTime = ((TLocalTime)timems) / 1000.0; TLocalTime localTime = ((TLocalTime)timems) / 1000.0;
LocalTimeDelta = localTime - LocalTime; a_LocalTimeDelta = localTime - LocalTime;
LocalTime = localTime;
if (_SkipAnimationOnce) if (_SkipAnimationOnce)
{ {
AnimationTimeDelta = 0.f; a_AnimationTimeDelta = 0.f;
_SkipAnimationOnce = false; _SkipAnimationOnce = false;
} }
else else
{ {
AnimationTimeDelta = (TAnimationTime)LocalTimeDelta; a_AnimationTimeDelta = (TGlobalAnimationTime)a_LocalTimeDelta;
AnimationTime += (TGlobalAnimationTime)LocalTimeDelta;
} }
} }
@ -105,6 +113,15 @@ void CGameTime::updateTime()
FramesPerSecondSmooth = _FpsSmoother.getSmoothValue(); FramesPerSecondSmooth = _FpsSmoother.getSmoothValue();
} }
void CGameTime::advanceTime(double f)
{
LocalTimeDelta = a_LocalTimeDelta * f;
LocalTime += LocalTimeDelta;
TGlobalAnimationTime atd = a_AnimationTimeDelta * f;
AnimationTimeDelta = (NL3D::TAnimationTime)atd;
AnimationTime += atd;
}
void CGameTime::skipAnimationOnce() void CGameTime::skipAnimationOnce()
{ {
_SkipAnimationOnce = true; _SkipAnimationOnce = true;

View file

@ -40,6 +40,9 @@ public:
static void updateTime(); static void updateTime();
/// Advance time to target time by factor f.
static void advanceTime(double f);
/// Used when loading, this will skip changing animation time on the next update /// Used when loading, this will skip changing animation time on the next update
/// (updates aren't called during loading) /// (updates aren't called during loading)
static void skipAnimationOnce(); static void skipAnimationOnce();

View file

@ -115,7 +115,7 @@ void CGraph::addValue (float value)
// //
CGraph FpsGraph ("fps", 10.0f, 10.0f, 100.0f, 100.0f, CRGBA(128,0,0,128), 1000, 40.0f); CGraph FpsGraph ("fps", 10.0f, 10.0f, 100.0f, 100.0f, CRGBA(128,0,0,128), 1000, 40.0f);
CGraph SpfGraph ("spf", 10.0f, 110.0f, 100.0f, 100.0f, CRGBA(0,128,0,128), 0, 200.0f); CGraph SpfGraph ("spf", 10.0f, 110.0f, 100.0f, 100.0f, CRGBA(0,128,0,128), 0, 0.1f);
CGraph DownloadGraph ("download", 10.0f, 260.0f, 100.0f, 100.0f, CRGBA(0,0,128,128), 1000, 1000.0f); CGraph DownloadGraph ("download", 10.0f, 260.0f, 100.0f, 100.0f, CRGBA(0,0,128,128), 1000, 1000.0f);
CGraph UploadGraph ("upload", 10.0f, 360.0f, 100.0f, 100.0f, CRGBA(0,128,128,128), 1000, 1000.0f); CGraph UploadGraph ("upload", 10.0f, 360.0f, 100.0f, 100.0f, CRGBA(0,128,128,128), 1000, 1000.0f);

View file

@ -427,6 +427,11 @@ void C3dMouseListener::updateCamera()
cpos = snapped+CVector(0.0f, 0.0f, GroundCamLimit); cpos = snapped+CVector(0.0f, 0.0f, GroundCamLimit);
_ViewHeight = cpos.z - getPosition().z; _ViewHeight = cpos.z - getPosition().z;
} }
if (StereoHMD)
{
// look at straight forward
tpos.z = cpos.z;
}
_Camera.lookAt(cpos, tpos); _Camera.lookAt(cpos, tpos);
} }

View file

@ -51,6 +51,7 @@
#if SBCLIENT_DEV_STEREO #if SBCLIENT_DEV_STEREO
# include <nel/3d/stereo_render.h> # include <nel/3d/stereo_render.h>
#endif /* #if SBCLIENT_DEV_STEREO */ #endif /* #if SBCLIENT_DEV_STEREO */
#include <nel/3d/stereo_hmd.h>
// Project includes // Project includes
#include "pacs.h" #include "pacs.h"
@ -151,6 +152,8 @@ LoadedOnline = false, LoadedOffline = false; // state
static IStereoRender *_StereoRender = NULL; static IStereoRender *_StereoRender = NULL;
#endif /* #if SBCLIENT_DEV_STEREO */ #endif /* #if SBCLIENT_DEV_STEREO */
static bool s_EnableBloom = false;
// //
// Prototypes // Prototypes
// //
@ -179,6 +182,9 @@ void releaseIngame();
void releaseOnline(); void releaseOnline();
void releaseOffline(); void releaseOffline();
void cbGraphicsDriver(CConfigFile::CVar &var); void cbGraphicsDriver(CConfigFile::CVar &var);
void cbSquareBloom(CConfigFile::CVar &var);
void cbDensityBloom(CConfigFile::CVar &var);
void cbEnableBloom(CConfigFile::CVar &var);
// //
// Functions // Functions
@ -306,11 +312,16 @@ void initCore()
Driver->setDisplay(UDriver::CMode(ConfigFile->getVar("ScreenWidth").asInt(), Driver->setDisplay(UDriver::CMode(ConfigFile->getVar("ScreenWidth").asInt(),
ConfigFile->getVar("ScreenHeight").asInt(), ConfigFile->getVar("ScreenHeight").asInt(),
ConfigFile->getVar("ScreenDepth").asInt(), ConfigFile->getVar("ScreenDepth").asInt(),
ConfigFile->getVar("ScreenFull").asInt()==0)); (ConfigFile->getVar("OpenGL").asInt() == 1 ? true : ConfigFile->getVar("ScreenFull").asInt()==0)));
// Set the cache size for the font manager(in bytes) // Set the cache size for the font manager(in bytes)
Driver->setFontManagerMaxMemory(2097152); Driver->setFontManagerMaxMemory(2097152);
// Create a Text context for later text rendering // Create a Text context for later text rendering
displayLoadingState("Initialize Text"); displayLoadingState("Initialize Text");
if (ConfigFile->getVar("OpenGL").asInt() == 1)
Driver->setMode(UDriver::CMode(ConfigFile->getVar("ScreenWidth").asInt(),
ConfigFile->getVar("ScreenHeight").asInt(),
ConfigFile->getVar("ScreenDepth").asInt(),
ConfigFile->getVar("ScreenFull").asInt()==0));
TextContext = Driver->createTextContext(CPath::lookup(ConfigFile->getVar("FontName").asString())); TextContext = Driver->createTextContext(CPath::lookup(ConfigFile->getVar("FontName").asString()));
TextContext->setShaded(true); TextContext->setShaded(true);
TextContext->setKeep800x600Ratio(false); TextContext->setKeep800x600Ratio(false);
@ -354,6 +365,7 @@ void initIngame()
//#ifdef NL_OS_WINDOWS //#ifdef NL_OS_WINDOWS
// playMusic(SBCLIENT_MUSIC_WAIT); // playMusic(SBCLIENT_MUSIC_WAIT);
//#endif //#endif
displayLoadingState("Initialize");
// Create a scene // Create a scene
Scene = Driver->createScene(false); Scene = Driver->createScene(false);
@ -362,7 +374,9 @@ void initIngame()
CBloomEffect::instance().setDriver(Driver); CBloomEffect::instance().setDriver(Driver);
CBloomEffect::instance().setScene(Scene); CBloomEffect::instance().setScene(Scene);
CBloomEffect::instance().init(ConfigFile->getVar("OpenGL").asInt() == 1); CBloomEffect::instance().init(ConfigFile->getVar("OpenGL").asInt() == 1);
CConfiguration::setAndCallback("SquareBloom", cbSquareBloom);
CConfiguration::setAndCallback("DensityBloom", cbDensityBloom);
CConfiguration::setAndCallback("EnableBloom", cbEnableBloom);
// Init the landscape using the previously created UScene // Init the landscape using the previously created UScene
displayLoadingState("Initialize Landscape"); displayLoadingState("Initialize Landscape");
initLandscape(); initLandscape();
@ -562,6 +576,8 @@ void releaseIngame()
MouseListener = NULL; MouseListener = NULL;
// release bloom effect // release bloom effect
CConfiguration::dropCallback("SquareBloom");
CConfiguration::dropCallback("DensityBloom");
CBloomEffect::instance().releaseInstance(); CBloomEffect::instance().releaseInstance();
Driver->deleteScene(Scene); Driver->deleteScene(Scene);
@ -673,15 +689,16 @@ void loopIngame()
// 02. Update Time (deltas) // 02. Update Time (deltas)
CGameTime::updateTime(); CGameTime::updateTime();
CGameTime::advanceTime(1.0);
// 03. Update Input (keyboard controls, etc) // 03. Update Incoming (network, receive messages)
updateNetwork();
// 04. Update Input (keyboard controls, etc)
Driver->EventServer.pump(); // Pump user input messages Driver->EventServer.pump(); // Pump user input messages
MouseListener->update(); MouseListener->update();
MouseListener->updateCamera(); MouseListener->updateCamera();
// 04. Update Incoming (network, receive messages)
updateNetwork();
// 05. Update Weather (sky, snow, wind, fog, sun) // 05. Update Weather (sky, snow, wind, fog, sun)
animateSky(LocalTimeDelta); animateSky(LocalTimeDelta);
@ -689,7 +706,7 @@ void loopIngame()
updateLandscape(); // Update the landscape updateLandscape(); // Update the landscape
// ... Update Animations (TEST) // ... Update Animations (TEST)
// ... updateAnimation();
// 07. Update Entities (collisions and actions) // 07. Update Entities (collisions and actions)
// - Move Other Entities (move//, animations, etc) // - Move Other Entities (move//, animations, etc)
@ -702,6 +719,7 @@ void loopIngame()
// 09. Update Camera (depends on entities) // 09. Update Camera (depends on entities)
updateCamera(); updateCamera();
if (StereoHMD) StereoHMD->updateCamera(0, &Camera);
// 10. Update Interface (login, ui, etc) // 10. Update Interface (login, ui, etc)
// ... // ...
@ -721,52 +739,98 @@ void loopIngame()
if (Driver->isLost()) nlSleep(10); if (Driver->isLost()) nlSleep(10);
else else
{ {
// call all 3d render thingies uint i = 0;
Driver->clearBuffers(CRGBA(127, 0, 0)); // if you see red, there's a problem with bloom or stereo render uint bloomStage = 0;
#if SBCLIENT_DEV_STEREO while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass()))
_StereoRender->calculateCameras(Camera.getObjectPtr()); // calculate modified matrices for the current camera
for (uint cameraId = 0; cameraId < _StereoRender->getCameraCount(); ++cameraId)
{ {
_StereoRender->getCamera(cameraId, Camera.getObjectPtr()); // get the matrix details for this camera ++i;
#endif /* #if SBCLIENT_DEV_STEREO */ if (StereoDisplay)
{
const CViewport &vp = StereoDisplay->getCurrentViewport();
Driver->setViewport(vp);
Scene->setViewport(vp);
SkyScene->setViewport(vp);
StereoDisplay->getCurrentFrustum(0, &Camera);
StereoDisplay->getCurrentFrustum(0, &SkyCamera);
StereoDisplay->getCurrentMatrix(0, &Camera);
}
// 01. Render Driver (background color) if (StereoDisplay)
CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) {
Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering StereoDisplay->beginRenderTarget();
}
if (!StereoDisplay || StereoDisplay->wantClear())
{
// 02. Render Sky (sky scene) if (s_EnableBloom)
updateSky(); // Render the sky scene before the main scene {
nlassert(bloomStage == 0);
CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render)
bloomStage = 1;
}
// 04. Render Scene (entity scene) // 01. Render Driver (background color)
Scene->render(); // Render Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering
}
// 05. Render Effects (flare) if (!StereoDisplay || StereoDisplay->wantScene())
updateLensFlare(); // Render the lens flare {
CBloomEffect::instance().endBloom(); // end the actual bloom effect visible in the scene // 02. Render Sky (sky scene)
updateSky(); // Render the sky scene before the main scene
// 06. Render Interface 3D (player names) // 04. Render Scene (entity scene)
CBloomEffect::instance().endInterfacesDisplayBloom(); // end bloom effect system after drawing the 3d interface (z buffer related) Scene->render(); // Render
#if SBCLIENT_DEV_STEREO // 05. Render Effects (flare)
_StereoRender->copyBufferToTexture(cameraId); // copy current buffer to the active stereorender texture if (!StereoHMD) updateLensFlare(); // Render the lens flare (left eye stretched with stereo...)
}
if (!StereoDisplay || StereoDisplay->wantInterface3D())
{
if (s_EnableBloom && bloomStage == 1)
{
// End the actual bloom effect visible in the scene.
if (StereoDisplay) Driver->setViewport(NL3D::CViewport());
CBloomEffect::instance().endBloom();
if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport());
bloomStage = 2;
}
// 06. Render Interface 3D (player names)
// ...
}
if (!StereoDisplay || StereoDisplay->wantInterface2D())
{
if (s_EnableBloom && bloomStage == 2)
{
// End bloom effect system after drawing the 3d interface (z buffer related).
if (StereoDisplay) Driver->setViewport(NL3D::CViewport());
CBloomEffect::instance().endInterfacesDisplayBloom();
if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport());
bloomStage = 0;
}
// 07. Render Interface 2D (chatboxes etc, optionally does have 3d)
updateCompass(); // Update the compass
updateRadar(); // Update the radar
updateGraph(); // Update the radar
if (ShowCommands) updateCommands(); // Update the commands panel
renderEntitiesNames(); // Render the name on top of the other players
updateInterface(); // Update interface
renderInformation();
if (!StereoDisplay) update3dLogo(); // broken with stereo
// 08. Render Debug (stuff for dev)
// ...
}
if (StereoDisplay)
{
StereoDisplay->endRenderTarget();
}
} }
_StereoRender->restoreCamera(Camera.getObjectPtr()); // restore the camera
_StereoRender->render(); // render everything together in the current mode
#endif /* #if SBCLIENT_DEV_STEREO */
// 07. Render Interface 2D (chatboxes etc, optionally does have 3d)
updateCompass(); // Update the compass
updateRadar(); // Update the radar
updateGraph(); // Update the radar
if (ShowCommands) updateCommands(); // Update the commands panel
updateAnimation();
renderEntitiesNames(); // Render the name on top of the other players
updateInterface(); // Update interface
renderInformation();
update3dLogo();
// 08. Render Debug (stuff for dev)
// ...
// 09. Render Buffer // 09. Render Buffer
Driver->swapBuffers(); Driver->swapBuffers();
@ -868,6 +932,8 @@ void renderInformation()
TextContext->setColor(CRGBA(255, 255, 255, 255)); TextContext->setColor(CRGBA(255, 255, 255, 255));
TextContext->setFontSize(14); TextContext->setFontSize(14);
TextContext->printfAt(0.01f, 0.99f, "%.2f(%.2f)fps %.3fs", FramesPerSecondSmooth, FramesPerSecond, (float)LocalTimeDelta); TextContext->printfAt(0.01f, 0.99f, "%.2f(%.2f)fps %.3fs", FramesPerSecondSmooth, FramesPerSecond, (float)LocalTimeDelta);
CVector camPos = Camera.getMatrix().getPos();
TextContext->printfAt(0.01f, 0.89f, "CAM POS: %.3f %.3f %.3f", camPos.x, camPos.y, camPos.z);
// one more frame // one more frame
FpsGraph.addValue(1.0f); FpsGraph.addValue(1.0f);
@ -884,6 +950,21 @@ void cbGraphicsDriver(CConfigFile::CVar &var)
NextGameState = GameStateReset; NextGameState = GameStateReset;
} }
void cbSquareBloom(CConfigFile::CVar &var)
{
CBloomEffect::instance().setSquareBloom(var.asBool());
}
void cbDensityBloom(CConfigFile::CVar &var)
{
CBloomEffect::instance().setDensityBloom((uint8)(var.asInt() & 0xFF));
}
void cbEnableBloom(CConfigFile::CVar &var)
{
s_EnableBloom = var.asBool();
}
// //
// Loading state procedure // Loading state procedure
// //
@ -1124,21 +1205,29 @@ sint main(int argc, char **argv)
FILE *f = _tfopen(_T(SBCLIENT_CONFIG_FILE_DEFAULT), _T("r")); FILE *f = _tfopen(_T(SBCLIENT_CONFIG_FILE_DEFAULT), _T("r"));
if (!f) if (!f)
{ {
OutputDebugString(" ******************************** \n"); f = _tfopen(_T(SBCLIENT_CONFIG_FILE), _T("r"));
OutputDebugString(" * CHANGING WORKING DIRECTORY * \n");
OutputDebugString(" ******************************** \n\n");
char cwd[256];
_tgetcwd(cwd, 256);
tstring workdir(cwd);
workdir += "\\..\\bin\\";
_tchdir(workdir.c_str());
f = _tfopen(_T(SBCLIENT_CONFIG_FILE_DEFAULT), _T("r"));
if (!f) if (!f)
{ {
OutputDebugString(" ******************************** \n"); OutputDebugString(" ******************************** \n");
OutputDebugString(" * DEFAULT CONFIG MISSING * \n"); OutputDebugString(" * CHANGING WORKING DIRECTORY * \n");
OutputDebugString(" ******************************** \n\n"); OutputDebugString(" ******************************** \n\n");
return EXIT_FAILURE; char cwd[256];
_tgetcwd(cwd, 256);
tstring workdir(cwd);
workdir = "R:\\build\\devw_x86\\bin\\Debug\\";
_tchdir(workdir.c_str());
f = _tfopen(_T(SBCLIENT_CONFIG_FILE_DEFAULT), _T("r"));
if (!f)
{
f = _tfopen(_T(SBCLIENT_CONFIG_FILE), _T("r"));
if (!f)
{
OutputDebugString(" ******************************** \n");
OutputDebugString(" * DEFAULT CONFIG MISSING * \n");
OutputDebugString(" ******************************** \n\n");
return EXIT_FAILURE;
}
}
} }
} }
fclose(f); fclose(f);

View file

@ -42,6 +42,8 @@ namespace NL3D {
class UScene; class UScene;
class UTextContext; class UTextContext;
class ULandscape; class ULandscape;
class IStereoDisplay;
class IStereoHMD;
} }
namespace SBCLIENT { namespace SBCLIENT {
@ -58,6 +60,8 @@ public:
}; };
extern NL3D::UDriver *Driver; extern NL3D::UDriver *Driver;
extern NL3D::IStereoDisplay *StereoDisplay;
extern NL3D::IStereoHMD *StereoHMD;
extern NL3D::UScene *Scene; extern NL3D::UScene *Scene;
extern NL3D::UTextContext *TextContext; extern NL3D::UTextContext *TextContext;
extern NLMISC::CConfigFile *ConfigFile; extern NLMISC::CConfigFile *ConfigFile;

View file

@ -37,7 +37,11 @@
#define SBCLIENT_ERASE_LOG true #define SBCLIENT_ERASE_LOG true
// version number // version number
#define SBCLIENT_VERSION "2.1.551" // 2.1
// - Bloom
// 2.2
// - OculusVR support
#define SBCLIENT_VERSION "2.2"
@ -45,6 +49,7 @@
#define SBCLIENT_DEV_SOUND 0 #define SBCLIENT_DEV_SOUND 0
#define SBCLIENT_DEV_STEREO 0 #define SBCLIENT_DEV_STEREO 0
#define SBCLIENT_DEV_MEMLEAK 0 #define SBCLIENT_DEV_MEMLEAK 0
#define SBCLIENT_DEV_PIXEL_PROGRAM 0
@ -70,7 +75,7 @@
# ifndef SNOWBALLS_CONFIG # ifndef SNOWBALLS_CONFIG
# define SBCLIENT_CONFIG_FILE "snowballs_client.cfg" # define SBCLIENT_CONFIG_FILE "snowballs_client.cfg"
# else # else
# define SBCLIENT_CONFIG_FILE SNOWBALLS_CONFIG "client.cfg" # define SBCLIENT_CONFIG_FILE SNOWBALLS_CONFIG "snowballs_client.cfg"
# endif # endif
#endif #endif