Merge multipass-stereo and game-device (Adds FXAA, removes DirectInput, updates Bloom, adds LibOVR 0.4 support)

This commit is contained in:
kaetemi 2014-09-12 15:29:19 +02:00
commit d9df2abec5
116 changed files with 7713 additions and 5419 deletions

View file

@ -31,6 +31,7 @@ namespace NL3D
class UDriver;
class UScene;
class CTextureUser;
//-----------------------------------------------------------------------------------------------------------
//---------------------------------------- CBloomEffect -----------------------------------------------------
@ -52,19 +53,14 @@ public:
// Destructor
~CBloomEffect();
// Called after the Driver initialization to indicate if OpenGL or Direct3D is used.
// They are some differences in bloom algorithm depending on this API choice.
// If bloom effect is activated and supported, private method init() is called to initialize
// textures and materials.
// initBloomEffect = false => directx
// initBloomEffect = true => opengl
void init(bool initBloomEffect);
// Called after the Driver initialization.
void init();
// must be called before init
void setDriver(UDriver *driver) { _Driver = driver; }
UDriver* getDriver() const { return _Driver; }
// must be called before initBloom
// must be called before applyBloom
void setScene(UScene *scene) { _Scene = scene; }
UScene* getScene() const { return _Scene; }
@ -76,6 +72,9 @@ public:
void setDensityBloom(uint8 densityBloom) { _DensityBloom = densityBloom; }
uint8 getDensityBloom() const { return _DensityBloom; }
// Applies bloom to the current render target
void applyBloom();
// Called at the beginning of renderAll method in the main loop, if window has been resized,
// reinitialize bloom textures according to new window size.
// The bloom texture (_InitText attribute) which is used as render target during scene render
@ -83,11 +82,11 @@ public:
// If window size exceeds 256*256 the textures used to apply blur are reinitialized with
// 256*256 size. If a dimension is less than 256, the texture is initialized with the nearer
// power of 2, lower than this window dimension.
void initBloom();
// void initBloom();
// Called at the end of renderAll method in the main loop, recover stretched texture, apply
// both blur passes, and the blending operation between initial render target and the blured one.
void endBloom();
// void endBloom();
// In OpenGL, the use of FBO implies that Z buffer values of scene render have been stored in
// a depth render target. Then, to display 3D interfaces, we must display them in the same FBO,
@ -95,15 +94,12 @@ public:
// This method is called at the end of interfaces display in the main loop, to display final render target
// (with added interfaces) in the color frame buffer.
// NB : In Direct3D, the final render target is displayed at the end of endBloom call.
void endInterfacesDisplayBloom();
// void endInterfacesDisplayBloom();
private:
// Initialize textures and materials.
void init();
// Initialize a bloom texture with new dimensions.
void initTexture(NLMISC::CSmartPtr<NL3D::ITexture> & tex, bool isMode2D, uint32 width, uint32 height);
// void initTexture(NLMISC::CSmartPtr<NL3D::ITexture> & tex, bool isMode2D, uint32 width, uint32 height);
// Called in endBloom method to build a blurred texture. Two passes (then two calls)
// are necessary : horizontal and vertical.
@ -130,6 +126,7 @@ private:
// density of bloom
uint8 _DensityBloom;
/*
// render target textures
// used to display scene
NLMISC::CSmartPtr<NL3D::ITexture> _InitText;
@ -140,13 +137,12 @@ private:
NLMISC::CSmartPtr<NL3D::ITexture> _BlurHorizontalTex;
// original render target
NLMISC::CSmartPtr<NL3D::ITexture> _OriginalRenderTarget;
*/
// materials
// used to display first texture in doBlur passes.
NL3D::UMaterial _BlurMat;
// used to display final render target texture in endInterfacesDisplayBloom call (OpenGL).
NL3D::UMaterial _DisplayInitMat;
// used to blend initial scene render target texture and blur texture according to a
// dest+src - dest*src blend operation.
NL3D::UMaterial _DisplayBlurMat;
@ -156,21 +152,24 @@ private:
// quads
NLMISC::CQuadUV _BlurQuad;
NLMISC::CQuadUV _DisplayQuad;
// openGL or Direct3D?
bool _InitBloomEffect;
// textures and materials already initialized?
bool _Init;
// current window dimensions
uint32 _WndWidth;
uint32 _WndHeight;
/*uint32 _WndWidth;
uint32 _WndHeight;*/
// Temporary variables used during applyBloom(...) ->
// current blur texture dimensions
uint32 _BlurWidth;
uint32 _BlurHeight;
// used as stretched texture from _InitText, as displayed texture in first blur pass,
// and as render target in second blur pass.
CTextureUser *_BlurFinalTex;
// used as render target in first blur pass, and as displayed texture on second blur pass.
CTextureUser *_BlurHorizontalTex;
// <-
};
} // NL3D

View file

@ -42,9 +42,6 @@
namespace NLMISC
{
class IEventEmitter;
struct IMouseDevice;
struct IKeyboardDevice;
struct IInputDeviceManager;
class CRect;
class CLog;
}
@ -75,6 +72,7 @@ struct IOcclusionQuery;
/// A Graphic Mode descriptor.
struct GfxMode
{
std::string DisplayDevice;
bool OffScreen;
bool Windowed;
uint16 Width;
@ -93,7 +91,7 @@ struct GfxMode
Frequency = 0;
AntiAlias = -1;
}
GfxMode(uint16 w, uint16 h, uint8 d, bool windowed = true, bool offscreen = false, uint frequency = 0, sint8 aa = -1);
GfxMode(uint16 w, uint16 h, uint8 d, bool windowed = true, bool offscreen = false, uint frequency = 0, sint8 aa = -1, const std::string &displayDevice = std::string());
};
// ****************************************************************************
@ -259,7 +257,7 @@ public:
virtual emptyProc getWindowProc() = 0;
virtual NLMISC::IEventEmitter *getEventEmitter() = 0;
/// Copy a string to system clipboard.
virtual bool copyTextToClipboard(const ucstring &text) = 0;
@ -362,7 +360,7 @@ public:
virtual void getDepthRange(float &znear, float &zfar) const = 0;
// @}
/// \name Textures
// @{
@ -434,7 +432,7 @@ public:
* Under OpenGL this simply returns the maximum number of texture stages (getNbTextureStages) in both return values.
*/
virtual void getNumPerStageConstant(uint &lightedMaterial, uint &unlightedMaterial) const = 0;
// [DEPRECATED] Return if this texture is a rectangle texture that requires RECT sampler (OpenGL specific pre-NPOT functionality)
virtual bool isTextureRectangle(ITexture *tex) const = 0;
@ -442,7 +440,7 @@ public:
virtual bool supportNonPowerOfTwoTextures() const = 0;
// @}
/// \name Texture operations
// @{
@ -536,7 +534,7 @@ public:
virtual bool isForceNormalize() const = 0;
// @}
/// \name Vertex Buffer Hard: Features
// @{
@ -737,7 +735,7 @@ public:
virtual uint getSwapVBLInterval() = 0;
// @}
@ -869,29 +867,6 @@ public:
/// x and y must be between 0.0 and 1.0
virtual void setMousePos(float x, float y) = 0;
/** Enable / disable low level mouse. This allow to take advantage of some options (speed of the mouse, automatic wrapping)
* It returns a interface to these parameters when it is supported, or NULL otherwise
* The interface pointer is valid as long as the low level mouse is enabled.
* A call to disable the mouse returns NULL, and restore the default mouse behavior
* NB : - In this mode the mouse cursor isn't drawn.
* - Calls to showCursor have no effects
* - Calls to setCapture have no effects
*/
virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive) = 0;
/** Enable / disable a low level keyboard.
* Such a keyboard can only send KeyDown and KeyUp event. It just consider the keyboard as a
* gamepad with lots of buttons...
* This returns a interface to some parameters when it is supported, or NULL otherwise.
* The interface pointer is valid as long as the low level keyboard is enabled.
* A call to disable the keyboard returns NULL, and restore the default keyboard behavior
*/
virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable) = 0;
/** Get the delay in ms for mouse double clicks.
*/
virtual uint getDoubleClickDelay(bool hardwareMouse) = 0;
/** If true, capture the mouse to force it to stay under the window.
* NB : this has no effects if a low level mouse is used
*/
@ -908,11 +883,6 @@ public:
// Change default scale for all cursors
virtual void setCursorScale(float scale) = 0;
/** Check whether there is a low level device manager available, and get its interface. Return NULL if not available
* From this interface you can deal with mouse and keyboard as above, but you can also manage game device (joysticks, joypads ...)
*/
virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager() = 0;
// @}
@ -1005,6 +975,9 @@ public:
) = 0;
// @}
/// Hack for bloom
virtual bool textureCoordinateAlternativeMode() const = 0;
/// \name Render state: Polygon mode
@ -1106,7 +1079,7 @@ public:
virtual bool supportVertexProgram(CVertexProgram::TProfile profile) const = 0;
/** Compile the given vertex program, return if successful.
* If a vertex program was set active before compilation,
* If a vertex program was set active before compilation,
* the state of the active vertex program is undefined behaviour afterwards.
*/
virtual bool compileVertexProgram(CVertexProgram *program) = 0;
@ -1133,7 +1106,7 @@ public:
virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const = 0;
/** Compile the given pixel program, return if successful.
* If a pixel program was set active before compilation,
* If a pixel program was set active before compilation,
* the state of the active pixel program is undefined behaviour afterwards.
*/
virtual bool compilePixelProgram(CPixelProgram *program) = 0;
@ -1160,7 +1133,7 @@ public:
virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const = 0;
/** Compile the given pixel program, return if successful.
* If a pixel program was set active before compilation,
* If a pixel program was set active before compilation,
* the state of the active pixel program is undefined behaviour afterwards.
*/
virtual bool compileGeometryProgram(CGeometryProgram *program) = 0;

View file

@ -34,7 +34,7 @@
#include "nel/3d/vertex_stream_manager.h"
#include "nel/3d/async_texture_manager.h"
#include "nel/3d/lod_character_manager.h"
#include "nel/3d/render_target_manager.h"
namespace NL3D
{
@ -71,6 +71,7 @@ protected:
bool _WindowInit;
CMatrixContext _CurrentMatrixContext;
CFontManager _FontManager;
CRenderTargetManager _RenderTargetManager;
// Components List.
typedef CPtrSet<CTextureUser> TTextureSet;
typedef CPtrSet<CTextContextUser> TTextContextSet;
@ -108,6 +109,11 @@ protected:
CMaterial _MatTextInternal;
CMaterial _MatTextStretchInternal;
// Default render target for effect pipeline
CTextureUser *_EffectRenderTarget;
UMaterial _MatRenderTarget;
CMaterial _MatRenderTargetInt;
NLMISC::CQuadUV _RenderTargetQuad;
// StaticInit
static bool _StaticInit;
@ -241,6 +247,16 @@ public:
// @}
/// Get the render target manager
virtual CRenderTargetManager &getRenderTargetManager() { return _RenderTargetManager; }
/// Set a texture the size of the window as render target
virtual void beginDefaultRenderTarget(uint32 width = 0, uint32 height = 0);
/// Draw the render target to the back buffer
virtual void endDefaultRenderTarget(UScene *scene);
/// \name Components gestion for Interface 2D/3D.
// @{
@ -410,21 +426,6 @@ public:
virtual bool fillBuffer (CBitmap &bitmap);
// @}
/// \name Mouse / Keyboards / Game devices
// @{
virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive);
//
virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable);
virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager();
/**
* wrapper for IEventEmitter::emulateMouseRawMode()
*/
virtual void emulateMouseRawMode(bool enable);
virtual uint getDoubleClickDelay(bool hardwareMouse);
/// show cursor if b is true, or hide it if b is false
virtual void showCursor (bool b);
/// x and y must be between 0.0 and 1.0

View file

@ -0,0 +1,84 @@
/**
* \file fxaa.h
* \brief CFXAA
* \date 2014-08-03 21:41GMT
* \author Jan Boon (Kaetemi)
* CFXAA
*/
/*
* Copyright (C) 2014 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_FXAA_H
#define NL3D_FXAA_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/u_material.h>
#include <nel/3d/vertex_buffer.h>
#define NL_STEREO_MAX_USER_CAMERAS 8
namespace NL3D {
class ITexture;
class CTextureUser;
class CPixelProgram;
class CVertexProgram;
/**
* \brief CFXAA
* \date 2014-08-03 21:41GMT
* \author Jan Boon (Kaetemi)
* CFXAA
*/
class CFXAA
{
public:
CFXAA(NL3D::UDriver *driver);
virtual ~CFXAA();
/// Apply effect to current render target. Render target must be managed by render target manager
virtual void applyEffect();
private:
UDriver *m_Driver;
NL3D::UMaterial m_Mat;
// NL3D::CVertexBuffer m_VB;
NLMISC::CQuadUV m_QuadUV;
CVertexProgram *m_VP;
CPixelProgram *m_PP;
uint m_Width;
uint m_Height;
}; /* class CFXAA */
} /* namespace NL3D */
#endif /* #ifndef NL3D_FXAA_H */
/* end of file */

View file

@ -0,0 +1,83 @@
/**
* \file render_target_manager.h
* \brief CRenderTargetManager
* \date 2014-07-30 21:30GMT
* \author Jan Boon (Kaetemi)
* CRenderTargetManager
*/
/*
* 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_RENDER_TARGET_MANAGER_H
#define NL3D_RENDER_TARGET_MANAGER_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/u_texture.h>
namespace NL3D {
class UDriver;
class ITexture;
class CTextureUser;
class CDriverUser;
struct CRenderTargetDescInt;
/**
* \brief CRenderTargetManager
* \date 2013-07-03 20:17GMT
* \author Jan Boon (Kaetemi)
* CRenderTargetManager
* Usage: Call 'getRenderTarget' when you start using a render target,
* call 'recycledRenderTarget' when the render target can be recycled.
* At end of frame call cleanup.
* Assumes semi-constant render target quantity between frames,
* except on changes of resolution or feature settings.
*/
class CRenderTargetManager
{
public:
CRenderTargetManager();
~CRenderTargetManager();
NL3D::CTextureUser *getRenderTarget(uint width, uint height, bool mode2D = false, UTexture::TUploadFormat format = UTexture::Auto);
void recycleRenderTarget(NL3D::CTextureUser *renderTarget);
void cleanup();
private:
friend class CDriverUser;
NL3D::UDriver *m_Driver;
std::vector<CRenderTargetDescInt *> m_RenderTargets;
}; /* class CRenderTargetManager */
} /* namespace NL3D */
#endif /* #ifndef NL3D_RENDER_TARGET_MANAGER_H */
/* end of file */

View file

@ -139,7 +139,7 @@ public:
* \param renderPart : The part of the scene that must be rendered
* \param newRender true If scene render is beginning. Otherwise other parts of the scene have already been rendered.
*/
void traverse(UScene::TRenderPart renderPart, bool newRender);
void traverse(UScene::TRenderPart renderPart, bool newRender, bool generateShadows);
//@}
/// \name RenderList.

View file

@ -157,7 +157,7 @@ public:
* \param doHrcPass set it to false to indicate that the CHrcTrav have not to be traversed. Useful to optimize if
* you know that NONE of your models have moved (a good example is a shoot of the scene from different cameras).
*/
void render(bool doHrcPass=true);
void render(bool doHrcPass = true);
/** Begin Part Rendering
* During beginPartRender()/endPartRender(), you can ask other scene to render their part, but you should
@ -171,10 +171,10 @@ public:
* WARNING: always must begin rendering with at least UScene::RenderOpaque, else shadows won't work
* WARNING: assert-crash if a part in 'rp' has already been rendered since the last beginPartRender()
*/
void renderPart(UScene::TRenderPart rp, bool doHrcPass=true);
void renderPart(UScene::TRenderPart rp, bool doHrcPass = true, bool doTrav = true, bool keepTrav = false);
/** End Part Rendering (commit model creation and deletion that were asked during rendering)
*/
void endPartRender();
void endPartRender(bool keepTrav = false);
//@}

View file

@ -96,8 +96,8 @@ public:
// render methods
virtual void render(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true);
virtual void beginPartRender();
virtual void renderPart(TRenderPart rp);
virtual void endPartRender(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true);
virtual void renderPart(TRenderPart rp, bool doHrcPass = true, bool doTrav = true, bool keepTrav = false);
virtual void endPartRender(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true, bool keepTrav = true);
// update async loading whithout a call to render
virtual void updateWaitingInstances(double ellapsedTime);

View file

@ -65,10 +65,17 @@ public:
/// Sets driver and generates necessary render targets
virtual void setDriver(NL3D::UDriver *driver);
void releaseTextures();
/*void releaseTextures();
void initTextures();
void setTextures();
void verifyTextures();
void verifyTextures();*/
void getTextures();
void recycleTextures();
/// Attach the driver to the display
virtual bool attachToDisplay();
/// Detach the driver from the display
virtual void detachFromDisplay();
/// Gets the required screen resolution for this device
virtual bool getScreenResolution(uint &width, uint &height);
@ -76,6 +83,8 @@ public:
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;
/// Get the original frustum of the camera
virtual void getOriginalFrustum(uint cid, NL3D::UCamera *camera) const;
/// Is there a next pass
virtual bool nextPass();
@ -89,14 +98,21 @@ public:
virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const;
/// At the start of a new render target
virtual bool wantClear();
virtual bool wantClear();
/// The 3D scene
virtual bool wantScene();
/// Scene post processing effects
virtual bool wantSceneEffects();
/// Interface within the 3D scene
virtual bool wantInterface3D();
/// 2D Interface
virtual bool wantInterface2D();
/// Is this the first 3D scene of the frame
virtual bool isSceneFirst();
/// Is this the last 3D scene of the frame
virtual bool isSceneLast();
/// 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
@ -116,9 +132,7 @@ private:
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;

View file

@ -94,6 +94,11 @@ public:
/// Sets driver and generates necessary render targets
virtual void setDriver(NL3D::UDriver *driver) = 0;
/// Attach the driver to the display, return true if attached
virtual bool attachToDisplay() = 0;
/// Detach the driver from the display
virtual void detachFromDisplay() = 0;
/// Gets the required screen resolution for this device
virtual bool getScreenResolution(uint &width, uint &height) = 0;
@ -101,6 +106,8 @@ public:
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;
/// Get the original frustum of the camera
virtual void getOriginalFrustum(uint cid, NL3D::UCamera *camera) const = 0;
/// Is there a next pass
virtual bool nextPass() = 0;
@ -114,20 +121,28 @@ public:
virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const = 0;
/// At the start of a new render target
virtual bool wantClear() = 0;
virtual bool wantClear() = 0;
/// The 3D scene
virtual bool wantScene() = 0;
/// Scene post processing effects
virtual bool wantSceneEffects() = 0;
/// Interface within the 3D scene
virtual bool wantInterface3D() = 0;
/// 2D Interface
virtual bool wantInterface2D() = 0;
/// Is this the first 3D scene of the frame
virtual bool isSceneFirst() = 0;
/// Is this the last 3D scene of the frame
virtual bool isSceneLast() = 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);
// List all devices. Device creation factories are no longer valid after re-calling this function
static void listDevices(std::vector<CStereoDeviceInfo> &devicesOut);
static IStereoDisplay *createDevice(const CStereoDeviceInfo &deviceInfo);
static void releaseUnusedLibraries();

View file

@ -53,6 +53,9 @@ public:
/// Get the HMD orientation
virtual NLMISC::CQuat getOrientation() const = 0;
/// Set the GUI reference
virtual void setInterfaceMatrix(const NL3D::CMatrix &matrix) = 0;
/// Get GUI center (1 = width, 1 = height, 0 = center)
virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const = 0;

View file

@ -44,7 +44,7 @@
#ifndef NL3D_STEREO_OVR_H
#define NL3D_STEREO_OVR_H
#ifdef HAVE_LIBOVR
#ifdef HAVE_LIBOVR_02
#include <nel/misc/types_nl.h>
@ -91,6 +91,8 @@ public:
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;
/// Get the original frustum of the camera
virtual void getOriginalFrustum(uint cid, NL3D::UCamera *camera) const;
/// Is there a next pass
virtual bool nextPass();
@ -121,6 +123,9 @@ public:
/// Get the HMD orientation
virtual NLMISC::CQuat getOrientation() const;
/// Set the GUI reference
virtual void setInterfaceMatrix(const NL3D::CMatrix &matrix);
/// Get GUI center (1 = width, 1 = height, 0 = center)
virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const;
@ -132,33 +137,37 @@ public:
/// Set the scale of the game in units per meter
virtual void setScale(float s);
/// Calculates internal camera information based on the reference camera
void initCamera(uint cid, const NL3D::UCamera *camera);
/// Render GUI
void renderGUI();
/// Checks if the device used by this class was actually created
bool isDeviceCreated();
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_RegularViewport;
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];
CFrustum m_OriginalFrustum[NL_STEREO_MAX_USER_CAMERAS];
CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS];
CMatrix m_InterfaceCameraMatrix;
mutable bool m_OrientationCached;
mutable NLMISC::CQuat m_OrientationCache;
UDriver *m_Driver;
NLMISC::CSmartPtr<NL3D::ITexture> m_BarrelTex;
NL3D::CTextureUser *m_BarrelTexU;
NL3D::CTextureUser *m_SceneTexture;
NL3D::UMaterial m_BarrelMat;
NL3D::CTextureUser *m_GUITexture;
NLMISC::CQuadUV m_BarrelQuadLeft;
NLMISC::CQuadUV m_BarrelQuadRight;
NLMISC::CRefPtr<CPixelProgramOVR> m_PixelProgram;

View file

@ -0,0 +1,225 @@
/**
* \file stereo_ovr.h
* \brief CStereoOVR
* \date 2014-08-04 16:21GMT
* \author Jan Boon (Kaetemi)
* CStereoOVR
*/
/*
* Copyright (C) 2014 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_04_H
#define NL3D_STEREO_OVR_04_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>
#include <nel/3d/u_driver.h>
#include <nel/3d/index_buffer.h>
#include <nel/3d/vertex_buffer.h>
struct ovrHmdDesc_;
typedef const ovrHmdDesc_ *ovrHmd;
namespace NL3D {
class ITexture;
class CTextureUser;
class CStereoOVRDeviceFactory;
#define NL_STEREO_MAX_USER_CAMERAS 8
#define NL_OVR_EYE_COUNT 2
/**
* \brief CStereoOVR
* \date 2014-08-04 16:21GMT
* \author Jan Boon (Kaetemi)
* CStereoOVR
*/
class CStereoOVR : public IStereoHMD
{
public:
CStereoOVR(const CStereoOVRDeviceFactory *factory);
virtual ~CStereoOVR();
/// Sets driver and generates necessary render targets
virtual void setDriver(NL3D::UDriver *driver);
/// Attach the driver to the display
virtual bool attachToDisplay();
/// Detach the driver from the display
virtual void detachFromDisplay();
/// 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;
/// Get the original frustum of the camera
virtual void getOriginalFrustum(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();
/// Scene post processing effects
virtual bool wantSceneEffects();
/// Interface within the 3D scene
virtual bool wantInterface3D();
/// 2D Interface
virtual bool wantInterface2D();
/// Is this the first 3D scene of the frame
virtual bool isSceneFirst();
/// Is this the last 3D scene of the frame
virtual bool isSceneLast();
/// 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;
/// Set the GUI reference
virtual void setInterfaceMatrix(const NL3D::CMatrix &matrix);
/// 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);
/// Calculates internal camera information based on the reference camera
void initCamera(uint cid, const NL3D::UCamera *camera);
/// Render GUI
void renderGUI();
/// Checks if the device used by this class was actually created
bool isDeviceCreated();
static void listDevices(std::vector<CStereoDeviceInfo> &devicesOut);
static bool isLibraryInUse();
static void releaseLibrary();
private:
ovrHmd m_DevicePtr;
bool m_DebugDevice;
int m_Stage;
int m_SubStage;
CViewport m_RegularViewport;
CViewport m_EyeViewport[NL_OVR_EYE_COUNT];
CFrustum m_EyeFrustumBase[NL_OVR_EYE_COUNT];
uint m_RenderTargetWidth;
uint m_RenderTargetHeight;
NLMISC::CVector2f m_EyeUVScaleOffset[NL_OVR_EYE_COUNT][2];
float m_EyeViewAdjustX[NL_OVR_EYE_COUNT];
CVertexBuffer m_VB[NL_OVR_EYE_COUNT];
CIndexBuffer m_IB[NL_OVR_EYE_COUNT];
uint32 m_NbTris[NL_OVR_EYE_COUNT];
CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS];
CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS];
CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS];
CFrustum m_OriginalFrustum[NL_STEREO_MAX_USER_CAMERAS];
CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS];
CMatrix m_InterfaceCameraMatrix;
mutable bool m_OrientationCached;
mutable NLMISC::CQuat m_OrientationCache;
UDriver *m_Driver;
CTextureUser *m_GUITexture;
NL3D::CTextureUser *m_SceneTexture;
UMaterial m_UnlitMat;
UDriver::CMode m_OriginalMode;
sint32 m_OriginalWinPosX;
sint32 m_OriginalWinPosY;
bool m_AttachedDisplay;
/*
NL3D::UMaterial m_BarrelMat;
NLMISC::CQuadUV m_BarrelQuadLeft;
NLMISC::CQuadUV m_BarrelQuadRight;
NLMISC::CRefPtr<CPixelProgramOVR> m_PixelProgram;*/
NLMISC::CVector m_EyePosition;
float m_Scale;
}; /* class CStereoOVR */
} /* namespace NL3D */
#endif /* HAVE_LIBOVR */
#endif /* #ifndef NL3D_STEREO_OVR_04_H */
/* end of file */

View file

@ -35,9 +35,6 @@
namespace NLMISC
{
struct IMouseDevice;
struct IKeyboardDevice;
struct IInputDeviceManager;
class CLog;
}
@ -63,6 +60,7 @@ class U3dMouseListener;
class ULight;
class UAnimationSet;
class UWaterEnvMap;
class CRenderTargetManager;
typedef void (*emptyProc)(void);
@ -94,6 +92,7 @@ public:
/// A Graphic Mode descriptor.
struct CMode
{
std::string DisplayDevice;
bool Windowed;
uint16 Width;
uint16 Height;
@ -110,8 +109,9 @@ public:
Frequency = 0;
AntiAlias = -1;
}
CMode(uint16 w, uint16 h, uint8 d, bool windowed= true, uint frequency = 0, sint8 aa = -1)
CMode(uint16 w, uint16 h, uint8 d, bool windowed= true, uint frequency = 0, sint8 aa = -1, const std::string &displayDevice = std::string())
{
DisplayDevice = displayDevice;
Windowed = windowed;
Width = w;
Height = h;
@ -309,6 +309,16 @@ public:
// @}
/// Get the render target manager
virtual CRenderTargetManager &getRenderTargetManager() =0;
/// Set a texture of specified size or of the size of the window as render target
virtual void beginDefaultRenderTarget(uint32 width = 0, uint32 height = 0) =0;
/// Draw the render target to the back buffer
virtual void endDefaultRenderTarget(UScene *scene) =0;
/// \name Components gestion for Interface 2D/3D.
// @{
@ -556,36 +566,6 @@ public:
/// \name Mouse / Keyboard / Gamedevices
// @{
/** Enable / disable low level mouse. This allow to take advantage of some options (speed of the mouse, automatic wrapping)
* It returns a interface to these parameters when it is supported, or NULL otherwise
* The interface pointer is valid as long as the low level mouse is enabled.
* A call to disable the mouse returns NULL, and restore the default mouse behaviour
* NB : - In this mode the mouse cursor isn't drawn.
* - Calls to showCursor have no effects
* - Calls to setCapture have no effects
*/
virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool hardware) = 0;
/** Enable / disable a low level keyboard.
* This returns a interface to some parameters when it is supported, or NULL otherwise.
* The interface pointer is valid as long as the low level keyboard is enabled.
* A call to disable the keyboard returns NULL, and restore the default keyboard behaviour.
*/
virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable) = 0;
/** Check whether there is a low level device manager available, and get its interface. Return NULL if not available.
* From this interface you can deal with mouse and keyboard as above, but you can also manage game devices (joysticks, joypads ...)
*/
virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager() = 0;
/**
* wrapper for IEventEmitter::emulateMouseRawMode()
*/
virtual void emulateMouseRawMode(bool enable) = 0;
// get delay used for mouse double click
virtual uint getDoubleClickDelay(bool hardwareMouse) = 0;
/** show cursor if b is true, or hide it if b is false
* NB: This has no effects if a low level mouse is used.
*/

View file

@ -134,14 +134,17 @@ public:
/** Render a part (see render() for what it does)
* beginPartRender() must have been called
* \param renderPart a combination of UScene::TRenderPart flags, allow to choose which part of the scene must be rendered
* \param doHrcPass set it to false to indicate that the CHrcTrav have not to be traversed. Useful to optimize if
* you know that NONE of your models have moved (a good example is a shoot of the scene from different cameras).
* \param doTrav set to false when processing a second frame for stereo rending to avoid unnecessary traversals.
* WARNING: always must begin rendering with at least UScene::RenderOpaque, else shadows won't work
* WARNING: assert-crash if a part in 'rp' has already been rendered since the last beginPartRender()
*/
virtual void renderPart(UScene::TRenderPart rp) =0;
virtual void renderPart(UScene::TRenderPart rp, bool doHrcPass = true, bool doTrav = true, bool keepTrav = false) =0;
/** End Part Rendering (commit model creation and deletion that were asked during rendering)
*/
virtual void endPartRender(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true) =0;
virtual void endPartRender(bool updateWaitingInstances = true, bool restoreMatrixContextAfterRender = true, bool keepTrav = false) =0;
/** Update waiting instances and igs that are loaded asynchronously

View file

@ -1,204 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_DI_EVENT_EMITTER_H
#define NL_DI_EVENT_EMITTER_H
#include "types_nl.h"
#ifdef NL_OS_WINDOWS
#define DIRECTINPUT_VERSION 0x0800
#include "input_device_server.h"
#include "input_device_manager.h"
#include "event_emitter.h"
#include "smart_ptr.h"
#include "events.h"
#include "rect.h"
#include "game_device.h"
#ifndef NL_COMP_MINGW
# define NOMINMAX
#endif
#include <windows.h>
#include <dinput.h>
namespace NLMISC
{
class CWinEventEmitter;
class CDIKeyboard;
class CDIMouse;
struct IMouseDevice;
struct IKeyboardDevice;
//
struct EDirectInput : public EInputDevice
{
EDirectInput(const char *reason) : EInputDevice(reason) {}
};
//
struct EDirectInputLibNotFound : public EDirectInput
{
EDirectInputLibNotFound() : EDirectInput("can't found the direct input dll") {}
};
//
struct EDirectInputInitFailed : public EDirectInput
{
EDirectInputInitFailed() : EDirectInput("Direct input initialization failed") {}
};
//
struct EDirectInputCooperativeLevelFailed : public EDirectInput
{
EDirectInputCooperativeLevelFailed() : EDirectInput("Direct Input Device Cooperative level couldn't be set") {}
};
// Class to represent Direct Inputs events
struct CDIEvent : public IInputDeviceEvent
{
virtual bool operator < (const IInputDeviceEvent &ide) const
{
// just compare the dates
return Datas.dwTimeStamp < (safe_cast<const CDIEvent *>(&ide))->Datas.dwTimeStamp;
}
DIDEVICEOBJECTDATA Datas;
};
/**
* This manage events by using DirectInput8.
* This should be polled regularly.
* This can be mixed with a CWinEmitter (for example, you may have mouse using direct input, and keyboard using standard messages)
* \author Nicolas Vizerie
* \author Nevrax France
* \date 2002
*/
class CDIEventEmitter : public IEventEmitter, public IInputDeviceManager
{
public:
/** Build a Direct Input Event Emitter object. An exception containing the reason is thrown if the initialization failed.
* The obtained object must be released by deleting it.
* \param hinst the instance of the application.
* \param hwnd the main window of the application.
* \param we A windows eventsemitter. Can be NULL. Needed if you want to mix WIN32 events and Direct Input events
* (for example, a Direct Input Mouse and a Win32 Keyboard)
*/
static CDIEventEmitter *create(HINSTANCE hinst, HWND hwnd, CWinEventEmitter *we) throw(EDirectInput);
~CDIEventEmitter();
public:
/// This poll the direct input state, directly storing the result in the given server, or keeping the result in internal server if NULL.
void poll(CEventServer *server = NULL);
///\name From IDeviceManager, access to devices
//@{
// Test if a mouse has been created (by a call to getMouseDeivce)
virtual bool isMouseCreated() { return _Mouse != NULL; }
/** Create the mouse device if needed (one active at a time for that object, repeated calls returns the same pointer) and get an interface on it. An exception if thrown if it couldn't be obtained.
* If this object has a pointer on a win32 emiter, Win32 mouse messages are replaced by this mouse messages.
*/
virtual IMouseDevice *getMouseDevice(bool hardware) throw(EInputDevice);
/// remove the direct input mouse
virtual void releaseMouse();
/** Create the keyboard device if needed (one active at a time for that object, repeated calls returns the same pointer) and get an interface on it.
* If this object has a pointer on a win32 emiter, Win32 keyboard messages are replaced by this keyboard messages.
* NB: A direct input has no notion of localization or key combinations. See keyboard_device.h for more infos
*/
virtual IKeyboardDevice *getKeyboardDevice() throw(EInputDevice);
/// remove the direct input keyboard
virtual void releaseKeyboard();
// Enumerates current game devices (gamepads, joystick etc.). The result is stored in the given vector
virtual void enumerateGameDevice(TDeviceDescVect &descs) throw(EInputDevice);
// Create the given game device from its instance name. It also means that it will begin to sends inputs
virtual IGameDevice *createGameDevice(const std::string &instanceName) throw(EInputDevice);
// Release the given game device
virtual void releaseGameDevice(IGameDevice *);
//@}
/// from IEventEmitter
virtual void submitEvents(CEventServer &server, bool allWindows);
virtual void emulateMouseRawMode(bool enable);
// Build a TMouseButton value from the current buttons state
TMouseButton buildButtonsFlags() const;
// Build a TMouseButton value (but with no mouse values)
TMouseButton buildKeyboardButtonFlags() const
{
return (TMouseButton) (buildButtonsFlags() & (ctrlButton|shiftButton|altButton));
}
//================================================================
//================================================================
//================================================================
private:
typedef HRESULT (WINAPI * TPDirectInput8Create) (HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID* ppvOut, LPUNKNOWN punkOuter);
// Private internal server message, used to stored all messages internally before to dispatch them, when no server is supplied to poll(...
class CDIEventServer : CEventServer
{
friend class CDIEventEmitter;
public:
void setServer (CEventServer *server)
{
_Server = server;
}
private:
bool pumpEvent(CEvent *event)
{
CEventServer::pumpEvent(event);
_Server->postEvent (event);
return false;
}
private:
CEventServer *_Server;
};
private:
HWND _hWnd;
TMouseButton _ButtonsFlags;
NLMISC::CRefPtr<CWinEventEmitter> _WE;
static HMODULE _DirectInputLibHandle;
static TPDirectInput8Create _PDirectInput8Create;
static uint _NumCreatedInterfaces;
private:
static bool loadLib();
static void unloadLib();
//====
private:
CDIEventServer _InternalServer;
CInputDeviceServer _DeviceServer;
IDirectInput8 *_DInput8;
CDIMouse *_Mouse;
CDIKeyboard *_Keyboard;
private:
CDIEventEmitter(HWND hwnd, CWinEventEmitter *we);
};
} // NLMISC
#endif // NL_WINDOWS
#endif // NL_DX_EVENT_EMITTER_H
/* End of dx_event_emitter.h */

View file

@ -49,19 +49,6 @@ public:
* \param server
*/
virtual void submitEvents(CEventServer & server, bool allWindows) = 0;
/**
* Instruct the event emitter to send CGDMouseMove instead of CEventMouseMove.
*
* On windows, the mouse device can be set into RawMode. Using this mode,
* CGDMouseMove events (only containing the raw movement delta) are emitted
* instead of the normal CEventMouseMove events (containing the mouse position).
*
* On Linux and Mac OS X, there is no MouseDevice implementation, all the
* events are created by the event emitter. So the event emitter has to
* emulate the mouse raw mode.
*/
virtual void emulateMouseRawMode(bool) = 0;
};

View file

@ -47,7 +47,6 @@ public:
const IEventEmitter *getEmitter(uint index) const;
/// From IEventEmitter. This call submitEvents on all the emitters
virtual void submitEvents(CEventServer &server, bool allWindows);
virtual void emulateMouseRawMode(bool enable);
virtual bool copyTextToClipboard(const ucstring &text);
virtual bool pasteTextFromClipboard(ucstring &text);

View file

@ -1,114 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_GAME_DEVICE_H
#define NL_GAME_DEVICE_H
#include "types_nl.h"
#include "input_device.h"
#include <string>
#include <vector>
namespace NLMISC
{
/// Describe a game device
struct CGameDeviceDesc
{
// type of the device
enum TDevType { GamePad, Joystick, DontKnow, DevTypeLast } DevType;
// Friendly name for the instance. For example, "Joystick 1."
std::string InstanceName;
// Friendly name for the product
std::string ProductName;
// Tells whether this device is connected
bool Connected;
};
// a list of game device description
typedef std::vector<CGameDeviceDesc> TDeviceDescVect;
/// for devices comparison. The 'Connected' field is ignored.
inline bool operator == (const CGameDeviceDesc &lhs, const CGameDeviceDesc &rhs)
{
return lhs.InstanceName == rhs.InstanceName && lhs.ProductName == rhs.ProductName;
}
//
inline bool operator != (const CGameDeviceDesc &lhs, const CGameDeviceDesc &rhs)
{
return !(lhs == rhs);
}
/**
* This abstract a joystick or gamepad
* \author Nicolas Vizerie
* \author Nevrax France
* \date 2002
*/
struct IGameDevice : public IInputDevice
{
enum TAxis { XAxis = 0, YAxis, ZAxis, /* translation */
RXAxis, RYAxis, RZAxis, /* rotations */
MaxNumAxis
};
/// Get a general description of this device
virtual const CGameDeviceDesc &getDescription() const = 0;
///\name Controls presence
//@{
// returns the number of buttons available on this game device
virtual uint getNumButtons() const = 0;
/** Check if the given axe is present on this game device
* NB : only absolute axis are managed
*/
virtual bool hasAxis(TAxis axis) const = 0;
// Check the number of sliders presents on this game device
virtual uint getNumSliders() const = 0;
// Check the number of point of views controls present on this game device
virtual uint getNumPOV() const = 0;
//@}
///\name Controls names. Must ensure that controls are present before calling these methods.
//@{
virtual const char *getButtonName(uint index) const = 0;
virtual const char *getAxisName(TAxis axis) const = 0;
virtual const char *getSliderName(uint index) const = 0;
virtual const char *getPOVName(uint index) const = 0;
//@}
///\name Controls state. Must ensure that controls are present before calling these methods.
//@{
// Return true if the given button is pushed.
virtual bool getButtonState(uint index) const = 0;
// Return a value in [-1, 1] for a translation axis, or an orientation.
virtual float getAxisValue(TAxis axis) const = 0;
// Return a value in [0, 1]
virtual float getSliderPos(uint index) const = 0;
// Return a CCW angle in degrees
virtual float getPOVAngle(uint index) const = 0;
//@}
};
} // NLMISC
#endif // NL_GAME_DEVICE_H
/* End of GAME_device.h */

View file

@ -1,209 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_GAME_DEVICE_EVENT_H
#define NL_GAME_DEVICE_EVENT_H
#include "types_nl.h"
#include "events.h"
#include "game_device.h"
namespace NLMISC
{
struct IMouseDevice;
struct IGameDevice;
const CClassId EventGDMouseMove(0x12142bc4, 0x43c73e74);
const CClassId EventGDButtonDownId(0x57141957, 0x3efb143a);
const CClassId EventGDButtonUpId(0x16105e06, 0x302536b2);
const CClassId EventGDAxisMovedId(0x073306, 0x41173626);
const CClassId EventGDSliderMovedId(0x68776586, 0x394a6916);
const CClassId EventGDPOVChanged(0x362851b9, 0x395c4d61);
//==========================================================================================
/// A raw mouse move message, expressed in mickeys (relative values)
class CGDMouseMove : public CEvent
{
public:
IMouseDevice *MD;
sint X, Y;
public:
CGDMouseMove(IEventEmitter *emitter, IMouseDevice *md, sint x, sint y) : CEvent(emitter, EventGDMouseMove), MD(md), X(x), Y(y)
{}
virtual CEvent *clone() const {return new CGDMouseMove(*this);}
};
//==========================================================================================
/**
* An event from a game device (joystick, joypad ...)
*/
class CGameDeviceEvent : public CEvent
{
public:
/// the game device this event come from
IGameDevice *GameDevice;
public:
CGameDeviceEvent(
IGameDevice *gameDevice,
IEventEmitter *emitter,
const CClassId &classId
)
: CEvent(emitter, classId),
GameDevice(gameDevice)
{}
};
//==========================================================================================
/** A button state has changed
*/
class CGDButton : public CGameDeviceEvent
{
public:
// index of the buttons that has been pushed
uint ButtonIndex;
bool Pushed;
public:
///
CGDButton(
uint buttonIndex,
bool pushed,
IGameDevice *gameDevice,
IEventEmitter *emitter,
const CClassId &classId
)
: CGameDeviceEvent(gameDevice, emitter, classId),
ButtonIndex(buttonIndex),
Pushed(pushed)
{}
};
//==========================================================================================
/** A button has been pushed
*/
class CGDButtonDown : public CGDButton
{
public:
///
CGDButtonDown(uint buttonIndex, IGameDevice *gameDevice, IEventEmitter *emitter)
: CGDButton(buttonIndex, true, gameDevice, emitter, EventGDButtonDownId)
{}
virtual CEvent *clone() const {return new CGDButtonDown(*this);}
};
//==========================================================================================
/** A button has been released
*/
class CGDButtonUp : public CGDButton
{
public:
///
CGDButtonUp(uint buttonIndex, IGameDevice *gameDevice, IEventEmitter *emitter)
: CGDButton(buttonIndex, false, gameDevice, emitter, EventGDButtonUpId)
{}
virtual CEvent *clone() const {return new CGDButtonUp(*this);}
};
//==========================================================================================
/// An axis has moved
class CGDAxisMoved : public CGameDeviceEvent
{
public:
IGameDevice::TAxis Axis;
// current position of the axis, ranges from -1.f to 1.f
float Value;
public:
CGDAxisMoved(
IGameDevice::TAxis axis,
float value,
IGameDevice *gameDevice,
IEventEmitter *emitter
)
: CGameDeviceEvent(gameDevice, emitter, EventGDAxisMovedId),
Axis(axis),
Value(value)
{}
virtual CEvent *clone() const {return new CGDAxisMoved(*this);}
};
//==========================================================================================
/// A slider position has changed
class CGDSliderMoved : public CGameDeviceEvent
{
public:
uint SliderIndex;
// current position of the slider, ranges from 0.f to 1.f
float SliderPos;
public:
CGDSliderMoved(
float sliderPos,
uint sliderIndex,
IGameDevice *gameDevice,
IEventEmitter *emitter
)
: CGameDeviceEvent(gameDevice, emitter, EventGDSliderMovedId),
SliderIndex(sliderIndex),
SliderPos(sliderPos)
{}
virtual CEvent *clone() const {return new CGDSliderMoved(*this);}
};
//==========================================================================================
/// A point of view control changed
class CGDPOVChanged : public CGameDeviceEvent
{
public:
uint POVIndex;
bool Centered;
// The POV angle, in degrees (CW)
float POVAngle;
public:
CGDPOVChanged(
bool centered,
float povAngle,
uint povIndex,
IGameDevice *gameDevice,
IEventEmitter *emitter
)
: CGameDeviceEvent(gameDevice, emitter, EventGDPOVChanged),
POVIndex(povIndex),
Centered(centered),
POVAngle(povAngle)
{}
virtual CEvent *clone() const {return new CGDPOVChanged(*this);}
};
} // NLMISC
#endif // NL_GAME_DEVICE_EVENT_H
/* End of game_device_event.h */

View file

@ -1,84 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_INPUT_DEVICE_H
#define NL_INPUT_DEVICE_H
#include "types_nl.h"
namespace NLMISC
{
class CEventServer;
class CInputDeviceServer;
struct IInputDeviceEvent;
/**
* Base class that wrap to a device
* \author Nicolas Vizerie
* \author Nevrax France
* \date 2002
*/
struct IInputDevice
{
/** Set the buffer size for this device (the number of samples it can retains).
* This return true if the size could be set
*/
virtual bool setBufferSize(uint size) = 0;
/// Get the buffer size for this device
virtual uint getBufferSize() const = 0;
///\name Device server specifics. You usually don't want to call these
//@{
/** For device server usage :
* Called at the beginning of each events retrieval.
* If a device doesn't support buffered datas, the state changes can be directly send to the event server.
* The default does nothing.
*/
virtual void begin(CEventServer * /* server */) {}
/** For device server usage :
* Poll all events from that device, and notify them to the given device server, so that they can be sorted between devices.
* This retrieves messages, but do not process them.
*/
virtual void poll(CInputDeviceServer *dev) = 0;
/** For device server usage :
* Process an event (eventually update this device state), and translate the message to a IEventServerMessage
*/
virtual void submit(IInputDeviceEvent *deviceEvent, CEventServer *server) = 0;
/** For device server usage :
* Says that the next message is for another device, or that it is the last message that will be received.
* This allow to pack several messages in one (for example, to sum up mouse moves until a click occurs)
* The default does nothing.
* The next message can be used to get a time stamp for example. It may be NULL is no next message is available
*/
virtual void transitionOccured(CEventServer * /* server */, const IInputDeviceEvent * /* nextMessage */) {}
//@}
// dtor
virtual ~IInputDevice() {}
};
} // NLMISC
#endif // NL_INPUT_DEVICE_H
/* End of input_device.h */

View file

@ -1,69 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_INPUT_DEVICE_MANAGER_H
#define NL_INPUT_DEVICE_MANAGER_H
#include "types_nl.h"
#include "game_device.h"
#include "common.h"
namespace NLMISC
{
struct IMouseDevice;
struct IKeyboardDevice;
struct EInputDevice : public Exception
{
EInputDevice(const char *reason) : Exception(reason) {}
};
/** Interface for objects that give low level access to devices (mouse, keyboard, joypads and joysticks).
* Generally an object implementing this interface will send the appropriate events when a device is 'created'.
* (Example of implementation : a direct input event emitter)
*/
struct IInputDeviceManager
{
// Test if a mouse has been created (by a call to getMouseDeivce)
virtual bool isMouseCreated() = 0;
/// Create the low level mouse device if needed (one active at a time for that object, repeated calls returns the same pointer). An exception if thrown if it couldn't be obtained.
virtual IMouseDevice *getMouseDevice(bool hardware) throw(EInputDevice) = 0;
/// remove the low level mouse
virtual void releaseMouse() = 0;
/// Create the low level keyboard device if needed (one active at a time for that object, repeated calls returns the same pointer). An exception if thrown if it couldn't be obtained.
virtual IKeyboardDevice *getKeyboardDevice() throw(EInputDevice) = 0;
/// remove the low level keyboard
virtual void releaseKeyboard() = 0;
// Enumerates current game devices (gamepads, joystick etc.). The result is stored in the given vector
virtual void enumerateGameDevice(TDeviceDescVect &descs) throw(EInputDevice) = 0;
// Create the given game device interface from its instance name. It also means that it will begin to sends events.
virtual IGameDevice *createGameDevice(const std::string &instanceName) throw(EInputDevice) = 0;
// Release the given game device.
virtual void releaseGameDevice(IGameDevice *gd) = 0;
};
} // NLMISC
#endif // NL_INPUT_DEVICE_MANAGER_H
/* End of device_manager.h */

View file

@ -1,84 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_INPUT_DEVICE_SERVER_H
#define NL_INPUT_DEVICE_SERVER_H
#include "types_nl.h"
#include <vector>
namespace NLMISC
{
class CEventServer;
struct IInputDevice;
struct IInputDeviceEvent;
/** Base class for an input device server. Unlike an event server, it manages several devices, and can sort their events (by date for example).
* It keeps a list of active devices.
* It can poll datas from every active device.
* It can sort devices messages to submit them in correct order to a CEventServer.
*/
class CInputDeviceServer
{
public:
/// register a device into this device server.
void registerDevice(IInputDevice *device);
/// remove a device from this server (but does not delete it).
void removeDevice(IInputDevice *device);
// returns the number of registered devices
uint getNumDevices() const { return (uint)_Devices.size(); }
// return a device
IInputDevice *getDevice(uint index) { return _Devices[index]; }
/// Test whether the given device is handled by this server.
bool isDevice(IInputDevice *device) const;
/// Retrieve datas from the devices, and submit them to the given CEventServer.
void poll(CEventServer *server);
/// Allow an input device to register an event. The event will then be deleted by this server
void submitEvent(IInputDeviceEvent *deviceEvent);
// dtor
virtual ~CInputDeviceServer() {}
private:
typedef std::vector<IInputDevice *> TDeviceCont;
typedef std::vector<IInputDeviceEvent *> TEventCont;
private:
TDeviceCont _Devices;
TEventCont _Events;
};
/** An event from an input device.
*/
struct IInputDeviceEvent
{
IInputDevice *Emitter; // the input device that emitted that event
// Used to sort events by time stamp.
virtual bool operator < (const IInputDeviceEvent &IInputDeviceEvent) const = 0;
virtual ~IInputDeviceEvent() {}
};
} // NLMISC
#endif // NL_INPUT_DEVICE_SERVER_H
/* End of input_device_server.h */

View file

@ -1,63 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_KEYBOARD_DEVICE_H
#define NL_KEYBOARD_DEVICE_H
#include "types_nl.h"
#include "events.h"
#include "input_device.h"
namespace NLMISC
{
/** Gives access to low level keyboard parameters
* - 'Shift' messages are replaced by RShift and LShift msg.
* - 'Control' messages are replaced by 'RControl' and 'LControl' msg.
* - 'Menu' (alternate) messages are replaced by 'RMenu' and 'LMenu' msg.
*/
struct IKeyboardDevice : public IInputDevice
{
/// Max number of supported keys
enum { NumKeys = 256 };
/// Get the delay before key repeat, in milliseconds
virtual uint getKeyRepeatDelay() const = 0;
/// Get the delay before key repeat, in milliseconds
virtual void setKeyRepeatDelay(uint delay) = 0;
/// Get the period before key repeat, in milliseconds
virtual uint getKeyRepeatPeriod() const = 0;
/// Get the period before key repeat, in milliseconds
virtual void setKeyRepeatPeriod(uint period) = 0;
/// Set a set of keys for which repetition is disabled
virtual void disableRepetition(const TKey *keyTab, uint numKey) = 0;
/// Get the number of disabled keys
virtual uint getNumDisabledRepetition() const = 0;
/** Get the disabled keys and stores in the given tab.
* NB: must ensure the destination table has the right size
* \see getNumDisabledKeys()
*/
virtual void getDisabledRepetitions(TKey *destTab) const = 0;
};
} // NLMISC
#endif // NL_KEYBOARD_DEVICE_H
/* End of keyboard_device.h */

View file

@ -1,130 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_MOUSE_DEVICE_H
#define NL_MOUSE_DEVICE_H
#include "types_nl.h"
#include "input_device.h"
namespace NLMISC
{
class CRect;
/// An interface to a low level mouse device
struct IMouseDevice : public IInputDevice
{
enum TAxisMode { Raw, Clamped, AxisModeLast };
enum TAxis { XAxis = 0, YAxis = 1, AxisLast };
enum TMessageMode { NormalMode, RawMode, MessageModeLast };
///\name Messages
//@{
/** Tells what messages should be sent :
* DEFAULT is 'raw' messages
* Raw messages : - no clamping nor frames applied
* - no speed applied
* - no factor applied
* - CGDMouseMove messages are sent
* - Move expressed in mickeys
* Normal messages : - CEventMouseMove messages are sent
* - A frame may clamp one or both axis
* - The mouse speed can be changed
*/
virtual void setMessagesMode(TMessageMode mode) = 0;
/// retrieve what kinds of messages are sent
virtual TMessageMode getMessagesMode() const = 0;
//@}
///\name Mouse MOVE, valid only
//@{
/** Set the mode of axis of the mouse. This can be raw, or clamped. In clamped mode, a frame is used to limit the move.
* NB : invalid in raw message mode
* \see setMouseFrame(const CRect &rect)
*/
virtual void setMouseMode(TAxis axis, TAxisMode axisMode) = 0;
/** returns the mode of the mouse for the given axis.
* NB : invalid in raw message mode
*/
virtual TAxisMode getMouseMode(TAxis axis) const = 0;
/** Set the mouse speed. It must be in the ]0, +inf] range, 1 gives the natural mouse speed.
* NB : invalid in raw message mode
*/
virtual void setMouseSpeed(float speed) = 0;
/** Get the mouse speed.
* NB : invalid in raw message mode
*/
virtual float getMouseSpeed() const = 0;
/** Set the mouse acceleration. It is the threshold in mickey, when start the acceleration. 0 means not acceleration.
*/
virtual void setMouseAcceleration(uint speed) = 0;
/** Get the mouse acceleration.
*/
virtual uint getMouseAcceleration() const = 0;
/** Set the current frame in which the mouse can move, expressed in pixels.
* NB do not forget to call setMouseFactors if you want the results to be reported in the 0-1 range.
* NB : invalid in raw message mode.
* \see setMouseFactors
*/
virtual void setMouseFrame(const CRect &rect) = 0;
/** Gives factor by which the mouse coordinates must be multiplied before an event is sent.
* The default factor is 1.
* NB : invalid in raw message mode.
*
* Example : this set a frame of 800x600 and reports event in the [0, 1] range.
* \code
* mouse->setMouseFrame(800, 600);
* mouse->setMouseMode(XAxis, IMouseDevice::Clamped);
* mouse->setMouseMode(YAxis, IMouseDevice::Clamped);
* mouse->setFactors(1.f / 800, 1.f / 600);
* \endcode
*/
virtual void setFactors(float xFactor, float yFactor) = 0;
/** Get the x factor, use to multiply the mouse position before an event is sent.
* NB : invalid in raw message mode.
* \see setFactors()
*/
virtual float getXFactor() const = 0;
/** Get the y factor, use to multiply the mouse position before an event is sent.
* NB : invalid in raw message mode.
* \see setFactors()
*/
virtual float getYFactor() const = 0;
//@}
// Get the current frame used for limiting mouse movements
virtual const CRect &getMouseFrame() const = 0;
// Set the maximum delay for a double click to be taken in account (in ms).
virtual void setDoubleClickDelay(uint ms) = 0;
// Get the maximum delay for double click (in ms)
virtual uint getDoubleClickDelay() const = 0;
// Force the position of the mouse, expressed in pixels
virtual void setMousePos(float x, float y) = 0;
/// From a delta of a mouse position input (eg from CEventMouseMove), deduce delta in mickeys (eg: like received from a CGDMouseMove)
virtual void convertStdMouseMoveInMickeys(float &dx, float &dy) const = 0;
};
} // NLMISC
#endif // NL_MOUSE_DEVICE_H
/* End of u_mouse_device.h */

View file

@ -100,8 +100,6 @@ public:
*/
bool processMessage (HWND hWnd, uint32 msg, WPARAM wParam, LPARAM lParam, CEventServer *server=NULL);
void emulateMouseRawMode(bool enable);
private:
CWinEventServer _InternalServer;
HWND _HWnd;

View file

@ -562,8 +562,13 @@ SOURCE_GROUP(Fx\\Particles\\lights FILES
ps_light.cpp
../../include/nel/3d/ps_light.h)
SOURCE_GROUP(Fx\\2d FILES
render_target_manager.cpp
../../include/nel/3d/render_target_manager.h
bloom_effect.cpp
../../include/nel/3d/bloom_effect.h
fxaa.cpp
fxaa_program.h
../../include/nel/3d/fxaa.h
deform_2d.cpp
../../include/nel/3d/deform_2d.h
heat_haze.cpp
@ -700,6 +705,9 @@ SOURCE_GROUP(Stereo FILES
stereo_ovr.cpp
stereo_ovr_fp.cpp
../../include/nel/3d/stereo_ovr.h
stereo_ovr_04.cpp
stereo_ovr_04_program.h
../../include/nel/3d/stereo_ovr_04.h
stereo_libvr.cpp
../../include/nel/3d/stereo_libvr.h
stereo_debugger.cpp

View file

@ -72,79 +72,47 @@ CBloomEffect::CBloomEffect()
_SquareBloom = true;
_DensityBloom = 128;
_Init = false;
_InitBloomEffect = false;
_BlurFinalTex = NULL;
_BlurHorizontalTex = NULL;
}
//-----------------------------------------------------------------------------------------------------------
CBloomEffect::~CBloomEffect()
{
if(_Init)
if (_Init)
{
if(!_DisplayInitMat.empty())
if (!_DisplayBlurMat.empty())
{
_DisplayInitMat.getObjectPtr()->setTexture(0, NULL);
if (_Driver) _Driver->deleteMaterial(_DisplayInitMat);
}
_InitText = NULL;
if(!_DisplayBlurMat.empty())
{
_DisplayBlurMat.getObjectPtr()->setTexture(0, NULL);
if (_Driver) _Driver->deleteMaterial(_DisplayBlurMat);
}
if(!_DisplaySquareBlurMat.empty())
if (!_DisplaySquareBlurMat.empty())
{
_DisplaySquareBlurMat.getObjectPtr()->setTexture(0, NULL);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(1, NULL);
if (_Driver) _Driver->deleteMaterial(_DisplaySquareBlurMat);
}
if(!_BlurMat.empty())
if (!_BlurMat.empty())
{
_BlurMat.getObjectPtr()->setTexture(0, NULL);
_BlurMat.getObjectPtr()->setTexture(1, NULL);
_BlurMat.getObjectPtr()->setTexture(2, NULL);
_BlurMat.getObjectPtr()->setTexture(3, NULL);
if (_Driver) _Driver->deleteMaterial(_BlurMat);
}
_BlurHorizontalTex = NULL;
_BlurFinalTex = NULL;
}
}
//-----------------------------------------------------------------------------------------------------------
void CBloomEffect::init(bool initBloomEffect)
{
_InitBloomEffect = initBloomEffect;
if(((CDriverUser *)_Driver)->getDriver()->supportBloomEffect())
init();
}
//-----------------------------------------------------------------------------------------------------------
void CBloomEffect::init()
{
_WndWidth = _Driver->getWindowWidth();
_WndHeight = _Driver->getWindowHeight();
if (!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect())
return;
CDriverUser *dru = static_cast<CDriverUser *>(_Driver);
IDriver *drv = dru->getDriver();
_BlurWidth = 256;
_BlurHeight = 256;
// initialize textures
_InitText = NULL;
_BlurHorizontalTex = NULL;
_BlurFinalTex = NULL;
if(_InitBloomEffect)
{
initTexture(_InitText, false, _WndWidth, _WndHeight);
}
initTexture(_BlurFinalTex, true, _BlurWidth, _BlurHeight);
initTexture(_BlurHorizontalTex, true, _BlurWidth, _BlurHeight);
// initialize blur material
_BlurMat = _Driver->createMaterial();
CMaterial * matObject = _BlurMat.getObjectPtr();
@ -187,22 +155,6 @@ void CBloomEffect::init()
matObject->texEnvArg1RGB(3, CMaterial::Constant, CMaterial::SrcColor);
matObject->texEnvArg2RGB(3, CMaterial::Previous, CMaterial::SrcColor);
// initialize display materials
if(_InitBloomEffect)
{
_DisplayInitMat = _Driver->createMaterial();
CMaterial * matObjectInit = _DisplayInitMat.getObjectPtr();
_DisplayInitMat.initUnlit();
_DisplayInitMat.setColor(CRGBA::White);
_DisplayInitMat.setBlend (false);
_DisplayInitMat.setAlphaTest (false);
matObjectInit->setBlendFunc (CMaterial::one, CMaterial::zero);
matObjectInit->setZWrite(false);
matObjectInit->setZFunc(CMaterial::always);
matObjectInit->setDoubleSided(true);
matObjectInit->setTexture(0, _InitText);
}
// initialize linear blur material
_DisplayBlurMat = _Driver->createMaterial();
CMaterial * matObjectFinal = _DisplayBlurMat.getObjectPtr();
@ -214,7 +166,7 @@ void CBloomEffect::init()
matObjectFinal->setZFunc(CMaterial::always);
matObjectFinal->setDoubleSided(true);
matObjectFinal->setTexture(0, _BlurFinalTex);
// matObjectFinal->setTexture(0, _BlurFinalTex);
matObjectFinal->texEnvOpRGB(0, CMaterial::Modulate);
matObjectFinal->texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor);
matObjectFinal->texEnvArg1RGB(0, CMaterial::Constant, CMaterial::SrcColor);
@ -230,163 +182,93 @@ void CBloomEffect::init()
matObjectFinal->setZFunc(CMaterial::always);
matObjectFinal->setDoubleSided(true);
matObjectFinal->setTexture(0, _BlurFinalTex);
matObjectFinal->texEnvOpRGB(0, CMaterial::Modulate);
matObjectFinal->texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor);
matObjectFinal->texEnvArg1RGB(0, CMaterial::Constant, CMaterial::SrcColor);
matObjectFinal->setTexture(1, _BlurFinalTex);
matObjectFinal->texEnvOpRGB(1, CMaterial::Modulate);
matObjectFinal->texEnvArg0RGB(1, CMaterial::Texture, CMaterial::SrcColor);
matObjectFinal->texEnvArg1RGB(1, CMaterial::Previous, CMaterial::SrcColor);
// initialize quads
_DisplayQuad.V0 = CVector(0.f, 0.f, 0.5f);
_DisplayQuad.V1 = CVector(1.f, 0.f, 0.5f);
_DisplayQuad.V2 = CVector(1.f, 1.f, 0.5f);
_DisplayQuad.V3 = CVector(0.f, 1.f, 0.5f);
_BlurQuad.V0 = CVector(-1.f, -1.f, 0.5f);
_BlurQuad.V1 = CVector(1.f, -1.f, 0.5f);
_BlurQuad.V2 = CVector(1.f, 1.f, 0.5f);
_BlurQuad.V3 = CVector(-1.f, 1.f, 0.5f);
if (drv->textureCoordinateAlternativeMode())
{
_BlurQuad.Uv0 = CUV(0.f, 1.f);
_BlurQuad.Uv1 = CUV(1.f, 1.f);
_BlurQuad.Uv2 = CUV(1.f, 0.f);
_BlurQuad.Uv3 = CUV(0.f, 0.f);
}
else
{
_BlurQuad.Uv0 = CUV(0.f, 0.f);
_BlurQuad.Uv1 = CUV(1.f, 0.f);
_BlurQuad.Uv2 = CUV(1.f, 1.f);
_BlurQuad.Uv3 = CUV(0.f, 1.f);
}
_Init = true;
}
//-----------------------------------------------------------------------------------------------------------
void CBloomEffect::initTexture(CSmartPtr<ITexture> & tex, bool isMode2D, uint32 width, uint32 height)
void CBloomEffect::applyBloom()
{
NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver();
tex = new CTextureBloom();
tex->setReleasable(false);
tex->resize(width, height);
tex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff);
tex->setWrapS(ITexture::Clamp);
tex->setWrapT(ITexture::Clamp);
((CTextureBloom *)tex.getPtr())->mode2D(isMode2D);
if(tex->TextureDrvShare==NULL || tex->TextureDrvShare->DrvTexture.getPtr()==NULL)
{
tex->setRenderTarget(true);
drvInternal->setupTexture(*tex);
}
}
//-----------------------------------------------------------------------------------------------------------
void CBloomEffect::initBloom() // clientcfg
{
if(!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect())
if (!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect())
return;
// don't activate bloom when PolygonMode is different from Filled
if (_Driver->getPolygonMode() != UDriver::Filled) return;
if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0)
if (_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0)
return;
if(!_Init)
if (!_Init)
init();
_OriginalRenderTarget = static_cast<CDriverUser *>(_Driver)->getDriver()->getRenderTarget();
CDriverUser *dru = static_cast<CDriverUser *>(_Driver);
IDriver *drv = dru->getDriver();
// if window resize, reinitialize textures
if(_WndWidth!=_Driver->getWindowWidth() || _WndHeight!=_Driver->getWindowHeight())
{
_WndWidth = _Driver->getWindowWidth();
_WndHeight = _Driver->getWindowHeight();
// backup
bool fogEnabled = _Driver->fogEnabled();
_Driver->enableFog(false);
if(_InitBloomEffect)
{
// release old SmartPtr
_DisplayInitMat.getObjectPtr()->setTexture(0, NULL);
_InitText = NULL;
NL3D::ITexture *renderTarget = drv->getRenderTarget();
nlassert(renderTarget);
nlassert(renderTarget->isBloomTexture());
initTexture(_InitText, false, _WndWidth, _WndHeight);
uint width = renderTarget->getWidth();
uint height = renderTarget->getHeight();
bool mode2D = static_cast<CTextureBloom *>(renderTarget)->isMode2D();
nlassert(renderTarget->getUploadFormat() == ITexture::Auto);
_DisplayInitMat.getObjectPtr()->setTexture(0, _InitText);
}
if (width >= 256) _BlurWidth = 256;
else _BlurWidth = raiseToNextPowerOf2(width) / 2;
if (height >= 256) _BlurHeight = 256;
else _BlurHeight = raiseToNextPowerOf2(height) / 2;
bool reinitBlurTextures = false;
if(_WndWidth<_BlurWidth || _WndHeight<_BlurHeight)
{
_BlurWidth = raiseToNextPowerOf2(_WndWidth)/2;
_BlurHeight = raiseToNextPowerOf2(_WndHeight)/2;
nlassert(!_BlurFinalTex);
_BlurFinalTex = _Driver->getRenderTargetManager().getRenderTarget(_BlurWidth, _BlurHeight, true);
nlassert(!_BlurHorizontalTex);
_BlurHorizontalTex = _Driver->getRenderTargetManager().getRenderTarget(_BlurWidth, _BlurHeight, true);
reinitBlurTextures = true;
}
_DisplayBlurMat.getObjectPtr()->setTexture(0, _BlurFinalTex->getITexture());
_DisplaySquareBlurMat.getObjectPtr()->setTexture(0, _BlurFinalTex->getITexture());
_DisplaySquareBlurMat.getObjectPtr()->setTexture(1, _BlurFinalTex->getITexture());
if(_WndWidth>256 && _BlurWidth!=256)
{
_BlurWidth = 256;
reinitBlurTextures = true;
}
CTextureUser texNull;
dru->setRenderTarget(texNull);
if(_WndHeight>256 && _BlurHeight!=256)
{
_BlurHeight = 256;
reinitBlurTextures = true;
}
if(reinitBlurTextures)
{
// release old SmartPtr
_DisplayBlurMat.getObjectPtr()->setTexture(0, NULL);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(0, NULL);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(1, NULL);
_BlurMat.getObjectPtr()->setTexture(0, NULL);
_BlurMat.getObjectPtr()->setTexture(1, NULL);
_BlurMat.getObjectPtr()->setTexture(2, NULL);
_BlurMat.getObjectPtr()->setTexture(3, NULL);
_BlurHorizontalTex = NULL;
_BlurFinalTex = NULL;
initTexture(_BlurFinalTex, true, _BlurWidth, _BlurHeight);
initTexture(_BlurHorizontalTex, true, _BlurWidth, _BlurHeight);
_DisplayBlurMat.getObjectPtr()->setTexture(0, _BlurFinalTex);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(0, _BlurFinalTex);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(1, _BlurFinalTex);
}
}
if (!_OriginalRenderTarget)
{
NL3D::CTextureUser txt = (_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser());
if(!(static_cast<CDriverUser *>(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight)))
{
nlwarning("setRenderTarget return false with initial texture for bloom effect\n");
return;
}
}
}
//-----------------------------------------------------------------------------------------------------------
void CBloomEffect::endBloom() // clientcfg
{
if(!_Driver->supportBloomEffect() || !_Init)
return;
// don't activate bloom when PolygonMode is different from Filled
if (_Driver->getPolygonMode() != UDriver::Filled) return;
if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0)
return;
CTextureUser txt1 = _OriginalRenderTarget ? CTextureUser(_OriginalRenderTarget) : ((_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser()));
CTextureUser txt2(_BlurFinalTex);
CRect rect1(0, 0, _WndWidth, _WndHeight);
// Stretch original render target into blur texture
CTextureUser txt1(renderTarget);
CTextureUser txt2(_BlurFinalTex->getITexture());
CRect rect1(0, 0, width, height);
CRect rect2(0, 0, _BlurWidth, _BlurHeight);
// stretch rect
((CDriverUser *) _Driver)->stretchRect(_Scene, txt1 , rect1,
txt2, rect2);
dru->stretchRect(_Scene, txt1, rect1, txt2, rect2);
_Driver->setMatrixMode2D11();
// horizontal blur pass
doBlur(true);
@ -395,7 +277,27 @@ void CBloomEffect::endBloom() // clientcfg
doBlur(false);
// apply blur with a blend operation
drv->setRenderTarget(renderTarget);
_Driver->setMatrixMode2D11();
applyBlur();
// cleanup material texture references
_DisplayBlurMat.getObjectPtr()->setTexture(0, NULL);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(0, NULL);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(1, NULL);
_BlurMat.getObjectPtr()->setTexture(0, NULL);
_BlurMat.getObjectPtr()->setTexture(1, NULL);
_BlurMat.getObjectPtr()->setTexture(2, NULL);
_BlurMat.getObjectPtr()->setTexture(3, NULL);
// restore
_Driver->enableFog(fogEnabled);
// recycle render targets
_Driver->getRenderTargetManager().recycleRenderTarget(_BlurFinalTex);
_BlurFinalTex = NULL;
_Driver->getRenderTargetManager().recycleRenderTarget(_BlurHorizontalTex);
_BlurHorizontalTex = NULL;
}
//-----------------------------------------------------------------------------------------------------------
@ -404,49 +306,6 @@ void CBloomEffect::applyBlur()
{
NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver();
/*if (_OriginalRenderTarget)
{
CTextureUser txt(_OriginalRenderTarget);
if(!(static_cast<CDriverUser *>(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight)))
{
nlwarning("setRenderTarget return false with original render target for bloom effect\n");
return;
}
}
// in opengl, display in init texture
else if(_InitBloomEffect)
{
CTextureUser txt(_InitText);
if(!(static_cast<CDriverUser *>(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight)))
{
nlwarning("setRenderTarget return false with initial texture for bloom effect\n");
return;
}
}*/
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
// initialize blur texture coordinates
if(_InitBloomEffect)
{
_BlurQuad.Uv0 = CUV(0.f, 0.f);
_BlurQuad.Uv1 = CUV(1.f, 0.f);
_BlurQuad.Uv2 = CUV(1.f, 1.f);
_BlurQuad.Uv3 = CUV(0.f, 1.f);
}
else
{
_BlurQuad.Uv0 = CUV(0.f, 1.f);
_BlurQuad.Uv1 = CUV(1.f, 1.f);
_BlurQuad.Uv2 = CUV(1.f, 0.f);
_BlurQuad.Uv3 = CUV(0.f, 0.f);
}
// initialize vertex program
drvInternal->activeVertexProgram(TextureOffsetVertexProgram);
drvInternal->setUniform4f(IDriver::VertexProgram, 8, 255.f, 255.f, 255.f, 255.f);
@ -469,59 +328,12 @@ void CBloomEffect::applyBlur()
matObjectFinal->texConstantColor(0, constCoeff);
// display quad
UCamera pCam = _Scene->getCam();
_Driver->setMatrixMode2D11();
_Driver->drawQuad(_BlurQuad, displayBlurMat);
_Driver->setMatrixMode3D(pCam);
// disable vertex program
drvInternal->activeVertexProgram(NULL);
}
//-----------------------------------------------------------------------------------------------------------
void CBloomEffect::endInterfacesDisplayBloom() // clientcfg
{
// Render from render target to screen if necessary.
// Don't do this when the blend was done to the screen or when rendering to a user provided rendertarget.
if ((_OriginalRenderTarget.getPtr() == NULL) && _InitBloomEffect)
{
if(!_Driver->supportBloomEffect() || !_Init)
return;
// don't activate bloom when PolygonMode is different from Filled
if (_Driver->getPolygonMode() != UDriver::Filled) return;
if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0)
return;
NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver();
CTextureUser txtNull;
((CDriverUser *)_Driver)->setRenderTarget(txtNull, 0, 0, 0, 0);
// initialize texture coordinates
float newU = drvInternal->isTextureRectangle(_InitText) ? (float)_WndWidth : 1.f;
float newV = drvInternal->isTextureRectangle(_InitText) ? (float)_WndHeight : 1.f;
_DisplayQuad.Uv0 = CUV(0.f, 0.f);
_DisplayQuad.Uv1 = CUV(newU, 0.f);
_DisplayQuad.Uv2 = CUV(newU, newV);
_DisplayQuad.Uv3 = CUV(0.f, newV);
// init material texture
// CMaterial * matObjectInit = _DisplayInitMat.getObjectPtr();
// display
UCamera pCam = _Scene->getCam();
_Driver->setMatrixMode2D11();
_Driver->drawQuad(_DisplayQuad, _DisplayInitMat);
_Driver->setMatrixMode3D(pCam);
}
_OriginalRenderTarget = NULL;
}
//-----------------------------------------------------------------------------------------------------------
void CBloomEffect::doBlur(bool horizontalBlur)
@ -531,17 +343,17 @@ void CBloomEffect::doBlur(bool horizontalBlur)
ITexture * endTexture;
// set displayed texture and render target texture of the pass
if(horizontalBlur)
if (horizontalBlur)
{
blurVec = CVector2f(1.f, 0.f);
startTexture = _BlurFinalTex;
endTexture = _BlurHorizontalTex;
startTexture = _BlurFinalTex->getITexture();
endTexture = _BlurHorizontalTex->getITexture();
}
else
{
blurVec = CVector2f(0.f, 1.f);
startTexture = _BlurHorizontalTex;
endTexture = _BlurFinalTex;
startTexture = _BlurHorizontalTex->getITexture();
endTexture = _BlurFinalTex->getITexture();
}
NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver();
@ -552,6 +364,7 @@ void CBloomEffect::doBlur(bool horizontalBlur)
nlwarning("setRenderTarget return false with blur texture for bloom effect\n");
return;
}
_Driver->setMatrixMode2D11();
// initialize vertex program
drvInternal->activeVertexProgram(TextureOffsetVertexProgram);
@ -561,20 +374,30 @@ void CBloomEffect::doBlur(bool horizontalBlur)
// set several decal constants in order to obtain in the render target texture a mix of color
// of a texel and its neighbored texels on the axe of the pass.
float decalL, decal2L, decalR, decal2R;
if(_InitBloomEffect)
if (drvInternal->textureCoordinateAlternativeMode())
{
if (horizontalBlur)
{
decalL = 0.5f;
decal2L = -0.5f;
decalR = 1.5f;
decal2R = 2.5f;
}
else
{
decalL = 0.0f;
decal2L = -1.0f;
decalR = 1.0f;
decal2R = 2.0f;
}
}
else
{
decalL = -0.5f;
decal2L = -1.5f;
decalR = 0.5f;
decal2R = 1.5f;
}
else
{
decalL = 0.f;
decal2L = -1.f;
decalR = 1.f;
decal2R = 2.f;
}
drvInternal->setUniform2f(IDriver::VertexProgram, 10, (decalR/(float)_BlurWidth)*blurVec.x, (decalR/(float)_BlurHeight)*blurVec.y);
drvInternal->setUniform2f(IDriver::VertexProgram, 11, (decal2R/(float)_BlurWidth)*blurVec.x, (decal2R/(float)_BlurHeight)*blurVec.y);
drvInternal->setUniform2f(IDriver::VertexProgram, 12, (decalL/(float)_BlurWidth)*blurVec.x, (decalL/(float)_BlurHeight)*blurVec.y);
@ -587,22 +410,13 @@ void CBloomEffect::doBlur(bool horizontalBlur)
matObject->setTexture(2, startTexture);
matObject->setTexture(3, startTexture);
// initialize quad
_BlurQuad.Uv0 = CUV(0.0f, 0.0f);
_BlurQuad.Uv1 = CUV(1.f, 0.0f);
_BlurQuad.Uv2 = CUV(1.f, 1.f);
_BlurQuad.Uv3 = CUV(0.0f, 1.f);
// display
UCamera pCam = _Scene->getCam();
_Driver->setMatrixMode2D11();
_Driver->drawQuad(_BlurQuad, _BlurMat);
// disable render target and vertex program
drvInternal->activeVertexProgram(NULL);
CTextureUser cu;
((CDriverUser *)_Driver)->setRenderTarget(cu, 0, 0, 0, 0);
_Driver->setMatrixMode3D(pCam);
}
}; // NL3D

View file

@ -32,7 +32,7 @@ namespace NL3D
{
// ***************************************************************************
const uint32 IDriver::InterfaceVersion = 0x6d; // gpu program interface
const uint32 IDriver::InterfaceVersion = 0x6e; // gpu program interface
// ***************************************************************************
IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" )
@ -123,8 +123,9 @@ bool IDriver::release(void)
// ***************************************************************************
GfxMode::GfxMode(uint16 w, uint16 h, uint8 d, bool windowed, bool offscreen, uint frequency, sint8 aa)
GfxMode::GfxMode(uint16 w, uint16 h, uint8 d, bool windowed, bool offscreen, uint frequency, sint8 aa, const std::string &displayDevice)
{
DisplayDevice = displayDevice;
Windowed = windowed;
Width = w;
Height = h;

View file

@ -25,8 +25,6 @@
#include "nel/3d/light.h"
#include "nel/3d/index_buffer.h"
#include "nel/misc/rect.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/mouse_device.h"
#include "nel/misc/dynloadlib.h"
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"
@ -1478,7 +1476,7 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r
D3DADAPTER_IDENTIFIER9 Identifier;
HRESULT Res;
Res = _D3D->GetAdapterIdentifier(gAdapter,0,&Identifier);
if (strstr(Identifier.Description,"PerfHUD") != 0)
{
nlinfo ("Setting up with PerfHUD");
@ -1511,6 +1509,7 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r
}
}
// _D3D->CreateDevice (adapter, _Rasterizer, _HWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &parameters, &_DeviceInterface);
// Check some caps
@ -1637,20 +1636,6 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r
// Setup the event emitter, and try to retrieve a direct input interface
_EventEmitter.addEmitter(we, true /*must delete*/); // the main emitter
// Try to get direct input
try
{
NLMISC::CDIEventEmitter *diee = NLMISC::CDIEventEmitter::create(GetModuleHandle(NULL), _HWnd, we);
if (diee)
{
_EventEmitter.addEmitter(diee, true);
}
}
catch(const EDirectInput &e)
{
nlinfo(e.what());
}
// Init some variables
_ForceDXTCCompression = false;
_AnisotropicFilter = 0;
@ -2010,13 +1995,6 @@ bool CDriverD3D::swapBuffers()
// todo hulud volatile
//_DeviceInterface->SetStreamSource(0, _VolatileVertexBufferRAM[1]->VertexBuffer, 0, 12);
// Is direct input running ?
if (_EventEmitter.getNumEmitters() > 1)
{
// flush direct input messages if any
NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1))->poll();
}
// End now
if (!endScene())
{

View file

@ -944,6 +944,7 @@ public:
virtual ITexture *getRenderTarget() const;
virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y, uint32 width,
uint32 height, uint32 mipmapLevel);
virtual bool textureCoordinateAlternativeMode() const { return true; };
virtual bool getRenderTargetSize (uint32 &width, uint32 &height);
virtual bool fillBuffer (CBitmap &bitmap);
@ -1033,11 +1034,6 @@ public:
// Change default scale for all cursors
virtual void setCursorScale(float scale);
virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive);
virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable);
virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager();
virtual uint getDoubleClickDelay(bool hardwareMouse);
// Lights
virtual uint getMaxLight () const;
virtual void setLight (uint8 num, const CLight& light);

View file

@ -19,8 +19,6 @@
#include "nel/3d/index_buffer.h"
#include "nel/3d/light.h"
#include "nel/misc/rect.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/mouse_device.h"
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"
#include "nel/3d/u_driver.h"

View file

@ -17,9 +17,6 @@
#include "stddirect3d.h"
#include "driver_direct3d.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/mouse_device.h"
using namespace std;
using namespace NLMISC;
@ -466,121 +463,6 @@ bool CDriverD3D::isSystemCursorCaptured()
return GetCapture() == _HWnd;
}
// ***************************************************************************
NLMISC::IMouseDevice* CDriverD3D::enableLowLevelMouse(bool enable, bool exclusive)
{
H_AUTO_D3D(CDriverD3D_enableLowLevelMouse);
NLMISC::IMouseDevice *res = NULL;
NLMISC::CDIEventEmitter *diee = NULL;
if (_EventEmitter.getNumEmitters() > 1)
diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
if (enable)
{
try
{
if (diee)
res = diee->getMouseDevice(exclusive);
}
catch (const EDirectInput &)
{
}
}
else
{
if (diee)
diee->releaseMouse();
}
return res;
}
// ***************************************************************************
NLMISC::IKeyboardDevice* CDriverD3D::enableLowLevelKeyboard(bool enable)
{
H_AUTO_D3D(CDriverD3D_enableLowLevelKeyboard);
NLMISC::IKeyboardDevice *res = NULL;
NLMISC::CDIEventEmitter *diee = NULL;
if (_EventEmitter.getNumEmitters() > 1)
diee = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
if (enable)
{
try
{
if (diee)
res = diee->getKeyboardDevice();
}
catch (const EDirectInput &)
{
}
}
else
{
if (diee)
diee->releaseKeyboard();
}
return res;
}
// ***************************************************************************
NLMISC::IInputDeviceManager* CDriverD3D::getLowLevelInputDeviceManager()
{
H_AUTO_D3D(CDriverD3D_getLowLevelInputDeviceManager);
NLMISC::IInputDeviceManager *res = NULL;
if (_EventEmitter.getNumEmitters() > 1)
res = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
return res;
}
// ***************************************************************************
uint CDriverD3D::getDoubleClickDelay(bool hardwareMouse)
{
H_AUTO_D3D(CDriverD3D_getDoubleClickDelay);
uint res = 250;
NLMISC::IMouseDevice *md = NULL;
if (_EventEmitter.getNumEmitters() >= 2)
{
NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
if (diee->isMouseCreated())
{
try
{
md = diee->getMouseDevice(hardwareMouse);
}
catch (const EDirectInput &)
{
// could not get device ..
}
}
}
if (md)
{
res = md->getDoubleClickDelay();
}
else
{
// try to read the good value from windows
res = ::GetDoubleClickTime();
}
return res;
}
bool CDriverD3D::convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &cursor, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY)
{
return convertBitmapToIcon(bitmap, cursor, iconWidth, iconHeight, iconDepth, col, hotSpotX, hotSpotY, true);

View file

@ -20,8 +20,6 @@
#include "nel/3d/light.h"
#include "nel/3d/index_buffer.h"
#include "nel/misc/rect.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/mouse_device.h"
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"
#include "nel/3d/u_driver.h"

View file

@ -21,8 +21,6 @@
#include "nel/3d/index_buffer.h"
#include "nel/3d/texture_bump.h"
#include "nel/misc/rect.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/mouse_device.h"
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"
#include "nel/3d/u_driver.h"
@ -648,7 +646,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat)
// Must separate texture setup and texture activation in 2 "for"...
// because setupTexture() may disable all stage.
if (matShader == CMaterial::Normal
if (matShader == CMaterial::Normal
|| ((matShader == CMaterial::Program) && (_PixelProgramUser->features().MaterialFlags & CProgramFeatures::TextureStages))
)
{
@ -670,7 +668,7 @@ bool CDriverD3D::setupMaterial(CMaterial &mat)
// Don't do it also for Specular because the EnvFunction and the TexGen may be special.
{
H_AUTO_D3D(CDriverD3D_setupMaterial_normalShaderActivateTextures)
if (matShader == CMaterial::Normal
if (matShader == CMaterial::Normal
|| ((matShader == CMaterial::Program) && (_PixelProgramUser->features().MaterialFlags & CProgramFeatures::TextureStages))
)
{

View file

@ -20,8 +20,6 @@
#include "nel/3d/light.h"
#include "nel/3d/index_buffer.h"
#include "nel/misc/rect.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/mouse_device.h"
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"
#include "nel/3d/u_driver.h"

View file

@ -20,8 +20,6 @@
#include "nel/3d/light.h"
#include "nel/3d/index_buffer.h"
#include "nel/misc/rect.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/mouse_device.h"
#include "nel/misc/fast_mem.h"
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"

View file

@ -20,8 +20,6 @@
#include "nel/3d/light.h"
#include "nel/3d/index_buffer.h"
#include "nel/misc/rect.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/mouse_device.h"
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"
#include "nel/3d/u_driver.h"

View file

@ -20,8 +20,6 @@
#include "nel/3d/light.h"
#include "nel/3d/index_buffer.h"
#include "nel/misc/rect.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/mouse_device.h"
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"
#include "nel/3d/u_driver.h"

View file

@ -28,8 +28,6 @@
#include "nel/3d/light.h"
#include "nel/3d/index_buffer.h"
#include "nel/misc/rect.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/mouse_device.h"
#include "nel/misc/hierarchical_timer.h"
#include "nel/misc/dynloadlib.h"
#include "driver_opengl_vertex_buffer_hard.h"
@ -236,6 +234,10 @@ CDriverGL::CDriverGL()
_CursorScale = 1.f;
_MouseCaptured = false;
#if defined(NL_OS_WINDOWS)
_BorderlessFullscreen = false;
#endif
_NeedToRestaureGammaRamp = false;
_win = EmptyWindow;
@ -483,7 +485,7 @@ bool CDriverGL::setupDisplay()
glLightModeli((GLenum)GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT);
#endif
}
if (_Extensions.ARBFragmentShader)
{
_ForceNativeFragmentPrograms = false;
@ -936,14 +938,6 @@ bool CDriverGL::swapBuffers()
}
#endif
#ifdef NL_OS_WINDOWS
if (_EventEmitter.getNumEmitters() > 1) // is direct input running ?
{
// flush direct input messages if any
NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1))->poll();
}
#endif
if (!_WndActive)
{
if (_AGPVertexArrayRange) _AGPVertexArrayRange->updateLostBuffers();
@ -1042,6 +1036,8 @@ bool CDriverGL::release()
// Call IDriver::release() before, to destroy textures, shaders and VBs...
IDriver::release();
nlassert(_DepthStencilFBOs.empty());
_SwapBufferCounter = 0;
// delete querries
@ -1085,7 +1081,7 @@ void CDriverGL::setupViewport (const class CViewport& viewport)
// Setup gl viewport
uint32 clientWidth, clientHeight;
getWindowSize(clientWidth, clientHeight);
getRenderTargetSize(clientWidth, clientHeight);
// Backup the viewport
_CurrViewport = viewport;
@ -1140,7 +1136,7 @@ void CDriverGL::setupScissor (const class CScissor& scissor)
// Setup gl viewport
uint32 clientWidth, clientHeight;
getWindowSize(clientWidth, clientHeight);
getRenderTargetSize(clientWidth, clientHeight);
// Backup the scissor
_CurrScissor= scissor;
@ -1509,7 +1505,7 @@ void CDriverGL::enableUsedTextureMemorySum (bool enable)
H_AUTO_OGL(CDriverGL_enableUsedTextureMemorySum )
if (enable)
{
{
nlinfo ("3D: PERFORMANCE INFO: enableUsedTextureMemorySum has been set to true in CDriverGL");
_TextureUsed.reserve(512);
}

View file

@ -146,6 +146,23 @@ public:
virtual uint getVisibleCount();
};
// ***************************************************************************
class CDepthStencilFBO : public NLMISC::CRefCount
{
public:
CDepthStencilFBO(CDriverGL *driver, uint width, uint height);
~CDepthStencilFBO();
uint Width;
uint Height;
GLuint DepthFBOId;
GLuint StencilFBOId;
private:
CDriverGL *m_Driver;
};
// ***************************************************************************
class CTextureDrvInfosGL : public ITextureDrvInfos
{
@ -173,12 +190,9 @@ public:
GLuint FBOId;
// depth stencil FBO id
GLuint DepthFBOId;
GLuint StencilFBOId;
bool InitFBO;
bool AttachDepthStencil;
bool UsePackedDepthStencil;
NLMISC::CSmartPtr<CDepthStencilFBO> DepthStencilFBO;
bool InitFBO;
// The current wrap modes assigned to the texture.
ITexture::TWrapMode WrapS;
@ -527,14 +541,6 @@ public:
// Change default scale for all cursors
virtual void setCursorScale(float scale);
virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive);
virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable);
virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager();
virtual uint getDoubleClickDelay(bool hardwareMouse);
virtual void getWindowSize (uint32 &width, uint32 &height);
virtual void getWindowPos (sint32 &x, sint32 &y);
@ -566,6 +572,8 @@ public:
virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y,
uint32 width, uint32 height, uint32 mipmapLevel);
virtual bool textureCoordinateAlternativeMode() const { return false; };
virtual bool getRenderTargetSize (uint32 &width, uint32 &height);
@ -693,6 +701,7 @@ private:
friend class CTextureDrvInfosGL;
friend class CVertexProgamDrvInfosGL;
friend class CPixelProgamDrvInfosGL;
friend class CDepthStencilFBO;
private:
// Version of the driver. Not the interface version!! Increment when implementation of the driver change.
@ -888,8 +897,11 @@ private:
// viewport before call to setRenderTarget, if BFO extension is supported
CViewport _OldViewport;
// Current FBO render target
CSmartPtr<ITexture> _RenderTargetFBO;
// Share the same backbuffer for FBO render targets with window size
std::vector<CDepthStencilFBO *> _DepthStencilFBOs;
// Num lights return by GL_MAX_LIGHTS
uint _MaxDriverLight;
@ -984,6 +996,12 @@ private:
EWindowStyle getWindowStyle() const;
bool setWindowStyle(EWindowStyle windowStyle);
#if defined(NL_OS_WINDOWS)
static BOOL CALLBACK monitorEnumProcFullscreen(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData);
bool _BorderlessFullscreen;
#endif
std::string _CurrentDisplayDevice;
// Methods to manage screen resolutions
bool restoreScreenMode();
bool saveScreenMode();

View file

@ -27,8 +27,6 @@
# endif // HAVE_XCURSOR
#endif // defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
#include "nel/misc/mouse_device.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/3d/u_driver.h"
#include "nel/misc/file.h"
@ -666,149 +664,6 @@ bool CDriverGL::isSystemCursorCaptured()
#endif
}
// ***************************************************************************
NLMISC::IMouseDevice* CDriverGL::enableLowLevelMouse(bool enable, bool exclusive)
{
H_AUTO_OGL(CDriverGL_enableLowLevelMouse);
NLMISC::IMouseDevice *res = NULL;
#ifdef NL_OS_WINDOWS
NLMISC::CDIEventEmitter *diee = NULL;
if (_EventEmitter.getNumEmitters() > 1)
diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
if (enable)
{
try
{
if (diee)
res = diee->getMouseDevice(exclusive);
}
catch (const EDirectInput &)
{
}
}
else
{
if (diee)
diee->releaseMouse();
}
#elif defined(NL_OS_MAC)
#elif defined (NL_OS_UNIX)
#endif
return res;
}
// ***************************************************************************
NLMISC::IKeyboardDevice* CDriverGL::enableLowLevelKeyboard(bool enable)
{
H_AUTO_OGL(CDriverGL_enableLowLevelKeyboard);
NLMISC::IKeyboardDevice *res = NULL;
#ifdef NL_OS_WINDOWS
NLMISC::CDIEventEmitter *diee = NULL;
if (_EventEmitter.getNumEmitters() > 1)
diee = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
if (enable)
{
try
{
if (diee)
res = diee->getKeyboardDevice();
}
catch (const EDirectInput &)
{
}
}
else
{
if (diee)
diee->releaseKeyboard();
}
#elif defined(NL_OS_MAC)
#elif defined (NL_OS_UNIX)
#endif
return res;
}
// ***************************************************************************
NLMISC::IInputDeviceManager* CDriverGL::getLowLevelInputDeviceManager()
{
H_AUTO_OGL(CDriverGL_getLowLevelInputDeviceManager);
NLMISC::IInputDeviceManager *res = NULL;
#ifdef NL_OS_WINDOWS
if (_EventEmitter.getNumEmitters() > 1)
res = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
#elif defined(NL_OS_MAC)
#elif defined (NL_OS_UNIX)
#endif
return res;
}
// ***************************************************************************
uint CDriverGL::getDoubleClickDelay(bool hardwareMouse)
{
H_AUTO_OGL(CDriverGL_getDoubleClickDelay);
uint res = 250;
#ifdef NL_OS_WINDOWS
NLMISC::IMouseDevice *md = NULL;
if (_EventEmitter.getNumEmitters() >= 2)
{
NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
if (diee->isMouseCreated())
{
try
{
md = diee->getMouseDevice(hardwareMouse);
}
catch (const EDirectInput &)
{
// could not get device ..
}
}
}
if (md)
{
res = md->getDoubleClickDelay();
}
else
{
// try to read the good value from windows
res = ::GetDoubleClickTime();
}
#elif defined(NL_OS_MAC)
// TODO: Missing Mac Implementation for getDoubleClickDelay
#elif defined (NL_OS_UNIX)
// TODO for Linux
#endif
return res;
}
bool CDriverGL::getBestCursorSize(uint srcWidth, uint srcHeight, uint &dstWidth, uint &dstHeight)
{
#ifdef NL_OS_WINDOWS

View file

@ -2087,14 +2087,16 @@ void CDriverGL::setupCloudPass (uint /* pass */)
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_SRC_ALPHA);
activateTexEnvColor (1, mat.getColor());
}
else
else if (ATICloudShaderHandle)
{
// TODO : for now the state is not cached in _CurrentTexEnvSpecial
nglBindFragmentShaderATI(ATICloudShaderHandle);
glEnable(GL_FRAGMENT_SHADER_ATI);
float cst[4] = { 0.f, 0.f, 0.f, mat.getColor().A / 255.f };
nglSetFragmentShaderConstantATI(GL_CON_0_ATI, cst);
/*
}
else
{
_DriverGLStates.activeTextureARB(0);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
// Operator.
@ -2130,7 +2132,6 @@ void CDriverGL::setupCloudPass (uint /* pass */)
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_CONSTANT_EXT );
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA);
*/
}
#endif
}

View file

@ -73,12 +73,8 @@ CTextureDrvInfosGL::CTextureDrvInfosGL(IDriver *drv, ItTexDrvInfoPtrMap it, CDri
#endif
FBOId = 0;
DepthFBOId = 0;
StencilFBOId = 0;
InitFBO = false;
AttachDepthStencil = true;
UsePackedDepthStencil = drvGl->supportPackedDepthStencil();
TextureUsedIdx = 0;
}
@ -98,9 +94,9 @@ CTextureDrvInfosGL::~CTextureDrvInfosGL()
_Driver->_TextureUsed[TextureUsedIdx] = NULL;
}
if(InitFBO)
{
#ifdef USE_OPENGLES
if (InitFBO)
{
nglDeleteFramebuffersOES(1, &FBOId);
if(AttachDepthStencil)
{
@ -108,24 +104,73 @@ CTextureDrvInfosGL::~CTextureDrvInfosGL()
if(!UsePackedDepthStencil)
nglDeleteRenderbuffersOES(1, &StencilFBOId);
}
#else
nglDeleteFramebuffersEXT(1, &FBOId);
if(AttachDepthStencil)
{
nglDeleteRenderbuffersEXT(1, &DepthFBOId);
if(!UsePackedDepthStencil)
nglDeleteRenderbuffersEXT(1, &StencilFBOId);
}
}
#endif
}
CDepthStencilFBO::CDepthStencilFBO(CDriverGL *driver, uint width, uint height)
{
nldebug("3D: Init shared FBO");
m_Driver = driver;
Width = width;
Height = height;
bool packedDepthStencil = driver->supportPackedDepthStencil();
nglGenRenderbuffersEXT(1, &DepthFBOId);
if (packedDepthStencil)
StencilFBOId = DepthFBOId;
else
nglGenRenderbuffersEXT(1, &StencilFBOId);
if (packedDepthStencil)
{
//nldebug("3D: using packed depth stencil");
nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilFBOId);
nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, width, height);
}
else
{
nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthFBOId);
nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height);
/*
nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilFBOId);
nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, width, height);
*/
}
nlassert(DepthFBOId);
nlassert(StencilFBOId);
driver->_DepthStencilFBOs.push_back(this);
}
CDepthStencilFBO::~CDepthStencilFBO()
{
// driver remove
m_Driver->_DepthStencilFBOs.erase(std::find(m_Driver->_DepthStencilFBOs.begin(), m_Driver->_DepthStencilFBOs.end(), this));
if (DepthFBOId)
{
nldebug("3D: Release shared FBO");
nglDeleteRenderbuffersEXT(1, &DepthFBOId);
if (StencilFBOId == DepthFBOId)
StencilFBOId = 0;
DepthFBOId = 0;
}
if (StencilFBOId)
{
nglDeleteRenderbuffersEXT(1, &StencilFBOId);
StencilFBOId = 0;
}
}
// ***************************************************************************
bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex)
{
if(!InitFBO)
if (!InitFBO)
{
if(tex->isBloomTexture())
if (tex->isBloomTexture())
{
AttachDepthStencil = !((CTextureBloom*)tex)->isMode2D();
}
@ -179,49 +224,33 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex)
#else
// generate IDs
nglGenFramebuffersEXT(1, &FBOId);
if(AttachDepthStencil)
{
nglGenRenderbuffersEXT(1, &DepthFBOId);
if(UsePackedDepthStencil)
StencilFBOId = DepthFBOId;
else
nglGenRenderbuffersEXT(1, &StencilFBOId);
}
//nldebug("3D: using depth %d and stencil %d", DepthFBOId, StencilFBOId);
// initialize FBO
nglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBOId);
nglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, TextureMode, ID, 0);
// attach depth/stencil render to FBO
// note: for some still unkown reason it's impossible to add
// a stencil buffer as shown in the respective docs (see
// opengl.org extension registry). Until a safe approach to add
// them is found, there will be no attached stencil for the time
// being, aside of using packed depth+stencil buffers.
if(AttachDepthStencil)
// attach depth stencil
if (AttachDepthStencil)
{
if(UsePackedDepthStencil)
for (std::vector<CDepthStencilFBO *>::iterator it(_Driver->_DepthStencilFBOs.begin()), end(_Driver->_DepthStencilFBOs.end()); it != end; ++it)
{
//nldebug("3D: using packed depth stencil");
nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilFBOId);
nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, tex->getWidth(), tex->getHeight());
if ((*it)->Width == tex->getWidth() && (*it)->Height == tex->getHeight())
{
DepthStencilFBO = (*it);
break;
}
}
else
if (!DepthStencilFBO)
{
nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthFBOId);
nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, tex->getWidth(), tex->getHeight());
/*
nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilFBOId);
nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, tex->getWidth(), tex->getHeight());
*/
DepthStencilFBO = new CDepthStencilFBO(_Driver, tex->getWidth(), tex->getHeight());
}
nglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, DepthFBOId);
GL_RENDERBUFFER_EXT, DepthStencilFBO->DepthFBOId);
nldebug("3D: glFramebufferRenderbufferExt(depth:24) = %X", nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
nglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, StencilFBOId);
GL_RENDERBUFFER_EXT, DepthStencilFBO->StencilFBOId);
nldebug("3D: glFramebufferRenderbufferExt(stencil:8) = %X", nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
}
#endif
@ -339,17 +368,7 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex)
#endif
if (AttachDepthStencil)
{
#ifdef USE_OPENGLES
nglDeleteRenderbuffersOES(1, &DepthFBOId);
#else
nglDeleteRenderbuffersEXT(1, &DepthFBOId);
#endif
if(!UsePackedDepthStencil)
#ifdef USE_OPENGLES
nglDeleteRenderbuffersOES(1, &StencilFBOId);
#else
nglDeleteRenderbuffersEXT(1, &StencilFBOId);
#endif
DepthStencilFBO = NULL;
}
}
@ -2260,11 +2279,8 @@ void CDriverGL::swapTextureHandle(ITexture &tex0, ITexture &tex1)
swap(t0->MinFilter, t1->MinFilter);
swap(t0->TextureMode, t1->TextureMode);
swap(t0->FBOId, t1->FBOId);
swap(t0->DepthFBOId, t1->DepthFBOId);
swap(t0->StencilFBOId, t1->StencilFBOId);
swap(t0->DepthStencilFBO, t1->DepthStencilFBO);
swap(t0->InitFBO, t1->InitFBO);
swap(t0->AttachDepthStencil, t1->AttachDepthStencil);
swap(t0->UsePackedDepthStencil, t1->UsePackedDepthStencil);
}
@ -2314,11 +2330,16 @@ bool CDriverGL::setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width
if(tex->isBloomTexture() && supportBloomEffect())
{
// NOTE: No support for mip map level here!
uint32 w, h;
getWindowSize(w, h);
getViewport(_OldViewport);
if (!width) width = tex->getWidth();
if (!height) height = tex->getHeight();
CViewport newVP;
newVP.init(0, 0, ((float)width/(float)w), ((float)height/(float)h));
setupViewport(newVP);
@ -2401,10 +2422,11 @@ bool CDriverGL::copyTargetToTexture (ITexture *tex,
bool CDriverGL::getRenderTargetSize (uint32 &width, uint32 &height)
{
H_AUTO_OGL(CDriverGL_getRenderTargetSize)
if (_TextureTarget)
NLMISC::CSmartPtr<ITexture> tex = _RenderTargetFBO ? _RenderTargetFBO : (_TextureTarget ? _TextureTarget : NULL);
if (tex)
{
width = _TextureTarget->getWidth();
height = _TextureTarget->getHeight();
width = tex->getWidth();
height = tex->getHeight();
}
else
{

View file

@ -38,8 +38,6 @@
# define _NET_WM_STATE_ADD 1
#endif // NL_OS_UNIX
#include "nel/misc/mouse_device.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/3d/u_driver.h"
#include "nel/misc/file.h"
@ -255,7 +253,7 @@ bool GlWndProc(CDriverGL *driver, XEvent &e)
unsigned long nitems_return = 0;
unsigned long bytes_after_return = 0;
long *data = NULL;
int status = XGetWindowProperty(driver->_dpy, driver->_win, XA_FRAME_EXTENTS, 0, 4, False, XA_CARDINAL, &type_return, &format_return, &nitems_return, &bytes_after_return, (unsigned char**)&data);
// succeeded to retrieve decoration size
@ -270,7 +268,7 @@ bool GlWndProc(CDriverGL *driver, XEvent &e)
driver->_DecorationWidth = e.xconfigure.x - driver->_WindowX;
driver->_DecorationHeight = e.xconfigure.y - driver->_WindowY;
}
// don't allow negative decoration sizes
if (driver->_DecorationWidth < 0) driver->_DecorationWidth = 0;
if (driver->_DecorationHeight < 0) driver->_DecorationHeight = 0;
@ -940,20 +938,6 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
// setup the event emitter, and try to retrieve a direct input interface
_EventEmitter.addEmitter(we, true /*must delete*/); // the main emitter
/// try to get direct input
try
{
NLMISC::CDIEventEmitter *diee = NLMISC::CDIEventEmitter::create(GetModuleHandle(NULL), _win, we);
if (diee)
{
_EventEmitter.addEmitter(diee, true);
}
}
catch(const EDirectInput &e)
{
nlinfo(e.what());
}
#elif defined(NL_OS_MAC)
if (wnd == EmptyWindow)
@ -1287,10 +1271,86 @@ static sint modeInfoToFrequency(XF86VidModeModeInfo *info)
// ***************************************************************************
#if defined(NL_OS_WINDOWS)
struct CMonitorEnumParams
{
public:
CDriverGL *Driver;
const char *DeviceName;
bool Success;
};
BOOL CALLBACK CDriverGL::monitorEnumProcFullscreen(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData)
{
CMonitorEnumParams *p = reinterpret_cast<CMonitorEnumParams *>(dwData);
MONITORINFOEXA monitorInfo;
memset(&monitorInfo, 0, sizeof(monitorInfo));
monitorInfo.cbSize = sizeof(monitorInfo);
GetMonitorInfoA(hMonitor, &monitorInfo);
nldebug("3D: Monitor: '%s'", monitorInfo.szDevice);
size_t devLen = strlen(monitorInfo.szDevice);
size_t targetLen = strlen(p->DeviceName);
nlassert(devLen < 32);
size_t minLen = min(devLen, targetLen);
if (!memcmp(monitorInfo.szDevice, p->DeviceName, minLen))
{
if (devLen == targetLen
|| (devLen < targetLen && (p->DeviceName[minLen] == '\\'))
|| (devLen > targetLen && (monitorInfo.szDevice[minLen] == '\\')))
{
nldebug("3D: Remapping '%s' to '%s'", p->DeviceName, monitorInfo.szDevice);
nldebug("3D: Found requested monitor at %i, %i", monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top);
p->Driver->_CurrentMode.Windowed = false;
p->Driver->setWindowStyle(CDriverGL::EWSWindowed);
p->Driver->setWindowSize(monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top);
LONG dwStyle = GetWindowLong(p->Driver->_win, GWL_STYLE);
SetWindowLong(p->Driver->_win, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW);
SetWindowPos(p->Driver->_win, NULL,
monitorInfo.rcMonitor.left,
monitorInfo.rcMonitor.top,
monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top,
SWP_FRAMECHANGED);
p->Driver->_WindowX = monitorInfo.rcMonitor.left;
p->Driver->_WindowY = monitorInfo.rcMonitor.top;
p->Driver->_CurrentDisplayDevice = std::string(p->DeviceName);
p->Driver->_BorderlessFullscreen = true;
p->Driver->_CurrentMode.Windowed = false;
p->Success = true;
return FALSE;
}
}
p->Success = false;
return TRUE; // continue
};
#endif
// ***************************************************************************
bool CDriverGL::setScreenMode(const GfxMode &mode)
{
H_AUTO_OGL(CDriverGL_setScreenMode)
nldebug("3D: setScreenMode");
#if defined(NL_OS_WINDOWS)
if (_BorderlessFullscreen)
{
_BorderlessFullscreen = false;
LONG dwStyle = GetWindowLong(_win, GWL_STYLE);
dwStyle |= WS_OVERLAPPEDWINDOW;
if (!_Resizable) dwStyle ^= WS_MAXIMIZEBOX|WS_THICKFRAME;
SetWindowLong(_win, GWL_STYLE, dwStyle);
SetWindowPos(_win, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
_CurrentMode.Windowed = true;
}
#endif
if (mode.Windowed)
{
// if fullscreen, switch back to desktop screen mode
@ -1300,13 +1360,17 @@ bool CDriverGL::setScreenMode(const GfxMode &mode)
return true;
}
if (_CurrentDisplayDevice != mode.DisplayDevice)
restoreScreenMode();
// save previous screen mode only if switching from windowed to fullscreen
if (_CurrentMode.Windowed)
saveScreenMode();
// if switching exactly to the same screen mode, doesn't change it
GfxMode previousMode;
if (getCurrentScreenMode(previousMode)
if (_CurrentDisplayDevice == mode.DisplayDevice
&& getCurrentScreenMode(previousMode)
&& mode.Width == previousMode.Width
&& mode.Height == previousMode.Height
&& mode.Depth == previousMode.Depth
@ -1315,7 +1379,9 @@ bool CDriverGL::setScreenMode(const GfxMode &mode)
#if defined(NL_OS_WINDOWS)
DEVMODE devMode;
const char *deviceName = mode.DisplayDevice.c_str();
DEVMODEA devMode;
memset(&devMode, 0, sizeof(DEVMODE));
devMode.dmSize = sizeof(DEVMODE);
devMode.dmDriverExtra = 0;
@ -1323,22 +1389,42 @@ bool CDriverGL::setScreenMode(const GfxMode &mode)
devMode.dmPelsWidth = mode.Width;
devMode.dmPelsHeight = mode.Height;
if(mode.Depth > 0)
if (mode.Depth > 0)
{
devMode.dmBitsPerPel = mode.Depth;
devMode.dmFields |= DM_BITSPERPEL;
}
if(mode.Frequency > 0)
if (mode.Frequency > 0)
{
devMode.dmDisplayFrequency = mode.Frequency;
devMode.dmFields |= DM_DISPLAYFREQUENCY;
}
if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
if (deviceName[0])
{
nlwarning("3D: Fullscreen mode switch failed");
return false;
// First attempt exclusive fullscreen
nldebug("3D: ChangeDisplaySettingsEx");
LONG resex;
if ((resex = ChangeDisplaySettingsExA(deviceName, &devMode, NULL, CDS_FULLSCREEN, NULL)) != DISP_CHANGE_SUCCESSFUL)
{
nlwarning("3D: Fullscreen mode switch failed (%i)", (sint)resex);
// Workaround, resize to monitor and make borderless
CMonitorEnumParams p;
p.DeviceName = deviceName;
p.Driver = this;
EnumDisplayMonitors(NULL, NULL, monitorEnumProcFullscreen, (LPARAM)&p);
return p.Success;
}
}
else
{
nldebug("3D: ChangeDisplaySettings");
if (ChangeDisplaySettingsA(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
nlwarning("3D: Fullscreen mode switch failed");
return false;
}
}
#elif defined(NL_OS_MAC)
@ -1744,7 +1830,11 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle)
dwNewStyle |= WS_VISIBLE;
if (dwStyle != dwNewStyle)
{
SetWindowLong(_win, GWL_STYLE, dwNewStyle);
if (windowStyle == EWSWindowed)
SetWindowPos(_win, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
}
// if (windowStyle == EWSMaximized && isVisible && !isMaximized)
// ShowWindow(_hWnd, SW_SHOWMAXIMIZED);
@ -1864,17 +1954,32 @@ bool CDriverGL::setMode(const GfxMode& mode)
if (!_DestroyWindow)
return true;
#if defined(NL_OS_WINDOWS)
// save relative cursor
POINT cursorPos;
BOOL cursorPosOk = isSystemCursorInClientArea()
&& GetCursorPos(&cursorPos)
&& ScreenToClient(_win, &cursorPos);
sint curX = (sint)cursorPos.x * (sint)mode.Width;
sint curY = (sint)cursorPos.y * (sint)mode.Height;
if (_BorderlessFullscreen)
ReleaseCapture();
#endif
if (!setScreenMode(mode))
return false;
// when changing window style, it's possible system change window size too
setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen);
if (!_BorderlessFullscreen)
{
// when changing window style, it's possible system change window size too
setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen);
if (!mode.Windowed)
_CurrentMode.Depth = mode.Depth;
if (!mode.Windowed)
_CurrentMode.Depth = mode.Depth;
setWindowSize(mode.Width, mode.Height);
setWindowPos(_WindowX, _WindowY);
setWindowSize(mode.Width, mode.Height);
setWindowPos(_WindowX, _WindowY);
}
switch (_CurrentMode.Depth)
{
@ -1883,6 +1988,19 @@ bool CDriverGL::setMode(const GfxMode& mode)
case 32: _ColorDepth = ColorDepth32; break;
}
#if defined(NL_OS_WINDOWS)
// restore relative cursor
if (cursorPosOk)
{
cursorPos.x = curX / (sint)mode.Width;
cursorPos.y = curY / (sint)mode.Height;
ClientToScreen(_win, &cursorPos);
SetCursorPos(cursorPos.x, cursorPos.y);
if (_BorderlessFullscreen)
SetCapture(_win);
}
#endif
// set color depth for custom cursor
updateCursor(true);
@ -2298,7 +2416,19 @@ void CDriverGL::setWindowPos(sint32 x, sint32 y)
#ifdef NL_OS_WINDOWS
SetWindowPos(_win, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
// save relative cursor
POINT cursorPos;
BOOL cursorPosOk = isSystemCursorInClientArea()
&& GetCursorPos(&cursorPos)
&& ScreenToClient(_win, &cursorPos);
SetWindowPos(_win, NULL, x, y, 0, 0, /*SWP_NOZORDER | SWP_NOACTIVATE |*/ SWP_NOSIZE);
if (cursorPosOk)
{
ClientToScreen(_win, &cursorPos);
SetCursorPos(cursorPos.x, cursorPos.y);
}
#elif defined(NL_OS_MAC)
// get the rect (position, size) of the screen with menu bar
@ -2469,7 +2599,7 @@ bool CDriverGL::createContext()
if (_EglContext == EGL_NO_CONTEXT)
{
return false;
}
}
// Make the context current
if (!eglMakeCurrent(_EglDisplay, _EglSurface, _EglSurface, _EglContext))

View file

@ -20,14 +20,13 @@
#include "nel/misc/event_emitter.h"
#include "nel/misc/event_server.h"
#include "nel/misc/events.h"
#include "nel/misc/game_device_events.h"
#include "nel/3d/driver.h"
#import "cocoa_opengl_view.h"
#include <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
namespace NLMISC
namespace NLMISC
{
class CCocoaEventEmitter : public IEventEmitter
@ -42,8 +41,8 @@ class CCocoaEventEmitter : public IEventEmitter
CEventServer* _server;
public:
CCocoaEventEmitter() :
_emulateRawMode(false),
CCocoaEventEmitter() :
_emulateRawMode(false),
_setToEmulateRawMode(false),
_driver(NULL),
_glView(nil),
@ -52,7 +51,6 @@ public:
void init(NL3D::IDriver*, CocoaOpenGLView*, bool eventLoop);
bool processMessage(NSEvent* event, CEventServer* server = NULL);
virtual void submitEvents(CEventServer& server, bool allWindows);
virtual void emulateMouseRawMode(bool enable);
bool handleQuitRequest();
virtual bool copyTextToClipboard(const ucstring &text);

View file

@ -83,7 +83,6 @@
#include "nel/misc/event_emitter_multi.h"
#include "nel/misc/time_nl.h"
#include "nel/misc/rect.h"
#include "nel/misc/mouse_device.h"
#include "nel/misc/dynloadlib.h"
#include "nel/misc/file.h"

View file

@ -23,7 +23,7 @@
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <X11/XKBlib.h>
#include <X11/XKBlib.h>
#include "nel/misc/debug.h"
@ -37,7 +37,7 @@ static Atom XA_WM_DELETE_WINDOW = 0;
namespace NLMISC {
CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _emulateRawMode(false), _driver(NULL)
CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _driver(NULL)
{
_im = 0;
_ic = 0;
@ -158,25 +158,6 @@ static Bool isMouseMoveEvent(Display *display, XEvent *event, XPointer arg)
return (event->type == MotionNotify);
}
void CUnixEventEmitter::emulateMouseRawMode(bool enable)
{
_emulateRawMode = enable;
if(_emulateRawMode)
{
XWindowAttributes xwa;
XGetWindowAttributes(_dpy, _win, &xwa);
XWarpPointer(_dpy, None, _win, None, None, None, None,
(xwa.width / 2), (xwa.height / 2));
// remove all outstanding mouse move events, they happened before the mouse
// was pulled back to 0.5 / 0.5, so a wrong movement delta would be
// reported otherwise
XEvent event;
while(XCheckIfEvent(_dpy, &event, &isMouseMoveEvent, NULL)) { };
}
}
#ifndef AltMask
# ifdef NL_OS_MAC
# define AltMask (8192)
@ -512,33 +493,13 @@ bool CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server)
{
TMouseButton button=getMouseButton (event.xbutton.state);
// if raw mode should be emulated
if(_emulateRawMode)
{
// when we just wrapped back the pointer to 0.5 / 0.5, ignore event
if(event.xbutton.x == xwa.width / 2 && event.xbutton.y == xwa.height / 2)
break;
// get the relative mouse position
float fX = (float) event.xbutton.x / (float) xwa.width;
float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height;
// post a CGDMouseMove with the movement delta to the event server
server->postEvent(
new CGDMouseMove(this, NULL /* no mouse device */,
event.xbutton.x - (xwa.width / 2),
(xwa.height / 2) - event.xbutton.y));
// post a normal mouse move event to the event server
server->postEvent (new CEventMouseMove (fX, fY, button, this));
// move the pointer back to the center of the window
XWarpPointer(_dpy, None, _win, None, None, None, None,
(xwa.width / 2), (xwa.height / 2));
}
// if in normal mouse mode
else
{
// get the relative mouse position
float fX = (float) event.xbutton.x / (float) xwa.width;
float fY = 1.0f - (float) event.xbutton.y / (float) xwa.height;
// post a normal mouse move event to the event server
server->postEvent (new CEventMouseMove (fX, fY, button, this));
}
break;
}
case KeyPress:

View file

@ -20,7 +20,6 @@
#include "nel/misc/types_nl.h"
#include "nel/misc/event_emitter.h"
#include "nel/misc/events.h"
#include "nel/misc/game_device_events.h"
#include "nel/3d/driver.h"
@ -56,11 +55,6 @@ public:
*/
virtual void submitEvents(CEventServer & server, bool allWindows);
/**
* enable or disable mouse raw mode
*/
virtual void emulateMouseRawMode(bool emulate);
/**
* process input-related events (mouse and keyboard)
*/

View file

@ -192,8 +192,11 @@ CDriverUser::CDriverUser (uintptr_t windowIcon, TDriver driver, emptyProc exitFu
_PBTri.lock (iba);
iba.setTri(0, 0, 1, 2);
_RenderTargetManager.m_Driver = this;
_ShapeBank._DriverUser = this;
_EffectRenderTarget = NULL;
NL_SET_IB_NAME(_PBLine, "CDriverUser::_PBLine");
NL_SET_IB_NAME(_PBTri, "CDriverUser::_PBTri");
}
@ -246,7 +249,7 @@ bool CDriverUser::setDisplay(nlWindow wnd, const CMode &mode, bool show, bool
NL3D_HAUTO_UI_DRIVER;
// window init.
if (_Driver->setDisplay(wnd, GfxMode(mode.Width, mode.Height, mode.Depth, mode.Windowed, false, mode.Frequency, mode.AntiAlias), show, resizeable))
if (_Driver->setDisplay(wnd, GfxMode(mode.Width, mode.Height, mode.Depth, mode.Windowed, false, mode.Frequency, mode.AntiAlias, mode.DisplayDevice), show, resizeable))
{
// Always true
nlverify (activate());
@ -290,7 +293,7 @@ bool CDriverUser::setDisplay(nlWindow wnd, const CMode &mode, bool show, bool
// ***************************************************************************
bool CDriverUser::setMode(const CMode& mode)
{
return _Driver->setMode(GfxMode(mode.Width, mode.Height, mode.Depth, mode.Windowed, false, mode.Frequency, mode.AntiAlias));
return _Driver->setMode(GfxMode(mode.Width, mode.Height, mode.Depth, mode.Windowed, false, mode.Frequency, mode.AntiAlias, mode.DisplayDevice));
}
// ----------------------------------------------------------------------------
@ -316,7 +319,7 @@ bool CDriverUser::getModes(std::vector<CMode> &modes)
bool res = _Driver->getModes(vTmp);
modes.clear();
for (uint i = 0; i < vTmp.size(); ++i)
modes.push_back(CMode(vTmp[i].Width, vTmp[i].Height, vTmp[i].Depth, vTmp[i].Windowed, vTmp[i].Frequency, vTmp[i].AntiAlias));
modes.push_back(CMode(vTmp[i].Width, vTmp[i].Height, vTmp[i].Depth, vTmp[i].Windowed, vTmp[i].Frequency, vTmp[i].AntiAlias, vTmp[i].DisplayDevice));
std::sort(modes.begin(), modes.end(), CModeSorter());
@ -1357,6 +1360,7 @@ void CDriverUser::swapBuffers()
NL3D_HAUTO_SWAP_DRIVER;
_Driver->swapBuffers();
_RenderTargetManager.cleanup();
}
// ***************************************************************************
@ -1609,36 +1613,6 @@ bool CDriverUser::fillBuffer (CBitmap &bitmap)
// ***************************************************************************
// ***************************************************************************
NLMISC::IMouseDevice *CDriverUser::enableLowLevelMouse(bool enable, bool exclusive)
{
NL3D_HAUTO_UI_DRIVER;
return _Driver->enableLowLevelMouse(enable, exclusive);
}
NLMISC::IKeyboardDevice *CDriverUser::enableLowLevelKeyboard(bool enable)
{
NL3D_HAUTO_UI_DRIVER;
return _Driver->enableLowLevelKeyboard(enable);
}
void CDriverUser::emulateMouseRawMode(bool enable)
{
_Driver->getEventEmitter()->emulateMouseRawMode(enable);
}
uint CDriverUser::getDoubleClickDelay(bool hardwareMouse)
{
NL3D_HAUTO_UI_DRIVER;
return _Driver->getDoubleClickDelay(hardwareMouse);
}
NLMISC::IInputDeviceManager *CDriverUser::getLowLevelInputDeviceManager()
{
NL3D_HAUTO_UI_DRIVER;
return _Driver->getLowLevelInputDeviceManager();
}
void CDriverUser::showCursor (bool b)
{
NL3D_HAUTO_UI_DRIVER;
@ -1974,9 +1948,7 @@ bool CDriverUser::setRenderTarget(class UTexture & uTex, uint32 x, uint32 y, uin
bool result = _Driver->setRenderTarget(tex, x, y, width, height, mipmapLevel, cubeFace);
CViewport currentViewport;
_Driver->getViewport(currentViewport);
setViewport(currentViewport);
setupMatrixContext();
return result;
}

View file

@ -73,6 +73,77 @@ void CDriverUser::deleteScene(UScene *scene)
_Scenes.erase((CSceneUser*)scene, "deleteScene(): Bad scene ptr");
}
// ***************************************************************************
void CDriverUser::beginDefaultRenderTarget(uint32 width, uint32 height)
{
if (_MatRenderTarget.empty())
{
_MatRenderTarget.attach(&_MatRenderTargetInt);
UMaterial &umat = _MatRenderTarget;
CMaterial &mat = _MatRenderTargetInt;
umat.initUnlit();
umat.setColor(CRGBA::White);
umat.setBlend(false);
umat.setAlphaTest(false);
mat.setBlendFunc(CMaterial::one, CMaterial::zero);
mat.setZWrite(false);
mat.setZFunc(CMaterial::always);
mat.setDoubleSided(true);
_RenderTargetQuad.V0 = CVector(0.f, 0.f, 0.5f);
_RenderTargetQuad.V1 = CVector(1.f, 0.f, 0.5f);
_RenderTargetQuad.V2 = CVector(1.f, 1.f, 0.5f);
_RenderTargetQuad.V3 = CVector(0.f, 1.f, 0.5f);
_RenderTargetQuad.Uv0 = CUV(0.f, 0.f);
_RenderTargetQuad.Uv1 = CUV(1.f, 0.f);
_RenderTargetQuad.Uv2 = CUV(1.f, 1.f);
_RenderTargetQuad.Uv3 = CUV(0.f, 1.f);
}
nlassert(!_EffectRenderTarget);
if (width == 0 || height == 0)
getWindowSize(width, height);
_EffectRenderTarget = getRenderTargetManager().getRenderTarget(width, height);
setRenderTarget(*_EffectRenderTarget);
}
// ***************************************************************************
void CDriverUser::endDefaultRenderTarget(UScene *scene)
{
nlassert(_EffectRenderTarget);
CTextureUser texNull;
setRenderTarget(texNull);
_MatRenderTarget.getObjectPtr()->setTexture(0, _EffectRenderTarget->getITexture());
UCamera pCam;
if (scene)
{
pCam = scene->getCam();
}
CViewport oldVp = getViewport();
CViewport vp = CViewport();
setViewport(vp);
setMatrixMode2D11();
bool fog = fogEnabled();
enableFog(false);
drawQuad(_RenderTargetQuad, _MatRenderTarget);
enableFog(fog);
setViewport(oldVp);
if (scene)
{
setMatrixMode3D(pCam);
}
_MatRenderTarget.getObjectPtr()->setTexture(0, NULL);
getRenderTargetManager().recycleRenderTarget(_EffectRenderTarget);
_EffectRenderTarget = NULL;
}
// ***************************************************************************
UTextContext *CDriverUser::createTextContext(const std::string fontFileName, const std::string fontExFileName)
{

291
code/nel/src/3d/fxaa.cpp Normal file
View file

@ -0,0 +1,291 @@
/**
* \file fxaa.cpp
* \brief CFXAA
* \date 2014-08-03 21:41GMT
* \author Jan Boon (Kaetemi)
* CFXAA
*/
/*
* Copyright (C) 2014 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/fxaa.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>
#include <nel/3d/render_target_manager.h>
using namespace std;
// using namespace NLMISC;
namespace NL3D {
namespace {
#include "fxaa_program.h"
} /* anonymous namespace */
CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_PP(NULL), m_VP(NULL), m_Width(~0), m_Height(~0)
{
nldebug("3D: Create FXAA");
CDriverUser *dru = static_cast<CDriverUser *>(driver);
NL3D::IDriver *drv = (dru)->getDriver();
if (drv->supportBloomEffect() && drv->supportNonPowerOfTwoTextures())
{
m_PP = new CPixelProgram();
// arbfp1
{
IProgram::CSource *source = new IProgram::CSource();
source->Features.MaterialFlags = CProgramFeatures::TextureStages;
source->Profile = IProgram::arbfp1;
source->setSourcePtr(a_arbfp1);
m_PP->addSource(source);
}
// ps_2_0
{
IProgram::CSource *source = new IProgram::CSource();
source->Features.MaterialFlags = CProgramFeatures::TextureStages;
source->Profile = IProgram::ps_2_0;
source->setSourcePtr(a_ps_2_0);
m_PP->addSource(source);
}
if (!drv->compilePixelProgram(m_PP))
{
nlwarning("3D: No supported pixel program for FXAA effect");
delete m_PP;
m_PP = NULL;
}
else
{
nldebug("3D: FXAA pixel program available");
}
}
if (!m_PP)
{
return;
}
// create vp
{
m_VP = new CVertexProgram();
// nelvp
{
IProgram::CSource *source = new IProgram::CSource();
source->Features.MaterialFlags = CProgramFeatures::TextureStages;
source->Profile = IProgram::nelvp;
source->setSourcePtr(a_nelvp);
m_VP->addSource(source);
}
if (!drv->compileVertexProgram(m_VP))
{
nlwarning("3D: No supported vertex program for FXAA effect");
delete m_VP;
m_VP = NULL;
delete m_PP;
m_PP = NULL;
}
else
{
nldebug("3D: FXAA vertex program available");
}
}
if (!m_VP)
{
return;
}
// create material and vb
{
m_Mat = m_Driver->createMaterial();
m_Mat.initUnlit();
m_Mat.setColor(CRGBA::White);
m_Mat.setBlend (false);
m_Mat.setAlphaTest (false);
NL3D::CMaterial *mat = m_Mat.getObjectPtr();
mat->setShader(NL3D::CMaterial::Normal);
mat->setBlendFunc(CMaterial::one, CMaterial::zero);
mat->setZWrite(false);
mat->setZFunc(CMaterial::always);
mat->setDoubleSided(true);
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);
if (drv->textureCoordinateAlternativeMode())
{
m_QuadUV.Uv0 = CUV(0.f, 1.f);
m_QuadUV.Uv1 = CUV(1.f, 1.f);
m_QuadUV.Uv2 = CUV(1.f, 0.f);
m_QuadUV.Uv3 = CUV(0.f, 0.f);
}
else
{
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);
}
/*CVertexBuffer &vb = m_VB;
vb.clearValueEx();
vb.addValueEx(CVertexBuffer::Position, CVertexBuffer::Float3);
vb.addValueEx(CVertexBuffer::TexCoord0, CVertexBuffer::Float2);
vb.addValueEx(CVertexBuffer::TexCoord1, CVertexBuffer::Float4);
vb.initEx();
vb.setPreferredMemory(CVertexBuffer::RAMVolatile, false);
vb.setNumVertices(4);*/
}
}
CFXAA::~CFXAA()
{
nldebug("3D: Destroy FXAA");
if (!m_Mat.empty())
{
m_Driver->deleteMaterial(m_Mat);
}
delete m_VP;
m_VP = NULL;
delete m_PP;
m_PP = NULL;
m_Driver = NULL;
}
void CFXAA::applyEffect()
{
if (!m_PP)
return;
CDriverUser *dru = static_cast<CDriverUser *>(m_Driver);
IDriver *drv = dru->getDriver();
// backup
bool fogEnabled = m_Driver->fogEnabled();
m_Driver->enableFog(false);
NL3D::ITexture *renderTarget = drv->getRenderTarget();
nlassert(renderTarget);
nlassert(renderTarget->isBloomTexture());
uint width = renderTarget->getWidth();
uint height = renderTarget->getHeight();
bool mode2D = static_cast<CTextureBloom *>(renderTarget)->isMode2D();
nlassert(renderTarget->getUploadFormat() == ITexture::Auto);
float fwidth = (float)width;
float fheight = (float)height;
float pwidth = 1.0f / fwidth;
float pheight = 1.0f / fheight;
float hpwidth = pwidth * 0.5f;
float hpheight = pheight * 0.5f;
float n = 0.5f;
//if (width != m_Width || height != m_Height)
/*{
// Build VB
m_Width = width;
m_Height = height;
CVertexBufferReadWrite vba;
m_VB.lock(vba);
vba.setValueFloat3Ex(CVertexBuffer::Position, 0, 0.f, 0.f, 0.5f); // BL
vba.setValueFloat3Ex(CVertexBuffer::Position, 1, 1.f, 0.f, 0.5f); // BR
vba.setValueFloat3Ex(CVertexBuffer::Position, 2, 1.f, 1.f, 0.5f); // TR
vba.setValueFloat3Ex(CVertexBuffer::Position, 3, 0.f, 1.f, 0.5f); // TL
vba.setValueFloat2Ex(CVertexBuffer::TexCoord0, 0, 0.f, 0.f);
vba.setValueFloat2Ex(CVertexBuffer::TexCoord0, 1, 1.f, 0.f);
vba.setValueFloat2Ex(CVertexBuffer::TexCoord0, 2, 1.f, 1.f);
vba.setValueFloat2Ex(CVertexBuffer::TexCoord0, 3, 0.f, 1.f);
vba.setValueFloat4Ex(CVertexBuffer::TexCoord1, 0, 0.f - hpwidth, 0.f - hpheight, 0.f + hpwidth, 0.f + hpheight);
vba.setValueFloat4Ex(CVertexBuffer::TexCoord1, 1, 1.f - hpwidth, 0.f - hpheight, 1.f + hpwidth, 0.f + hpheight);
vba.setValueFloat4Ex(CVertexBuffer::TexCoord1, 2, 1.f - hpwidth, 1.f - hpheight, 1.f + hpwidth, 1.f + hpheight);
vba.setValueFloat4Ex(CVertexBuffer::TexCoord1, 3, 0.f - hpwidth, 1.f - hpheight, 0.f + hpwidth, 1.f + hpheight);
}*/
// create render target
CTextureUser *otherRenderTarget = m_Driver->getRenderTargetManager().getRenderTarget(width, height, mode2D);
// swap render target
CTextureUser texNull;
dru->setRenderTarget(texNull);
drv->swapTextureHandle(*renderTarget, *otherRenderTarget->getITexture());
drv->setRenderTarget(renderTarget);
m_Driver->setMatrixMode2D11();
// debug
// m_Driver->clearBuffers(CRGBA(128, 128, 128, 128));
// activate program
bool vpok = drv->activeVertexProgram(m_VP);
nlassert(vpok);
bool ppok = drv->activePixelProgram(m_PP);
nlassert(ppok);
/*drv->setUniform4f(IDriver::PixelProgram, 0, -n / fwidth, -n / fheight, n / fwidth, n / fheight); // fxaaConsoleRcpFrameOpt
drv->setUniform4f(IDriver::PixelProgram, 1, -2.0f / fwidth, -2.0f / fheight, 2.0f / fwidth, 2.0f / fheight); // fxaaConsoleRcpFrameOpt2*/
drv->setUniform2f(IDriver::PixelProgram, 0, 1.0f / fwidth, 1.0f / fheight); // fxaaQualityRcpFrame
drv->setUniform1f(IDriver::PixelProgram, 1, 0.75f); // fxaaQualitySubpix
drv->setUniform1f(IDriver::PixelProgram, 2, 0.166f); // fxaaQualityEdgeThreshold
drv->setUniform1f(IDriver::PixelProgram, 3, 0.0833f); // fxaaQualityEdgeThresholdMin
drv->setUniformMatrix(IDriver::VertexProgram, 0, IDriver::ModelViewProjection, IDriver::Identity);
// drv->setUniform4f(IDriver::VertexProgram, 9, -hpwidth, -hpheight, hpwidth, hpheight);
// render effect
m_Mat.getObjectPtr()->setTexture(0, otherRenderTarget->getITexture());
/*drv->activeVertexBuffer(m_VB);
drv->renderRawQuads(*m_Mat.getObjectPtr(), 0, 1);*/
m_Driver->drawQuad(m_QuadUV, m_Mat);
m_Mat.getObjectPtr()->setTexture(0, NULL);
// deactivate program
drv->activeVertexProgram(NULL);
drv->activePixelProgram(NULL);
// restore
m_Driver->enableFog(fogEnabled);
// recycle render target
m_Driver->getRenderTargetManager().recycleRenderTarget(otherRenderTarget);
}
} /* namespace NL3D */
/* end of file */

View file

@ -0,0 +1,994 @@
const char *a_nelvp =
"!!VP1.0\n"
"DP4 o[HPOS].x, c[0], v[OPOS];\n"
"DP4 o[HPOS].y, c[1], v[OPOS];\n"
"DP4 o[HPOS].z, c[2], v[OPOS];\n"
"DP4 o[HPOS].w, c[3], v[OPOS];\n"
"MOV o[TEX0].xy, v[TEX0];\n"
// "ADD o[TEX1], v[TEX0].xyxy, c[9];\n"
"END\n";
const char *a_arbfp1_test =
"!!ARBfp1.0\n"
"OPTION ARB_precision_hint_fastest;\n"
"TEX result.color, fragment.texcoord[1].zwzw, texture[0], 2D;\n"
"END\n";
const char *a_arbfp1 =
"!!ARBfp1.0\n"
"OPTION ARB_precision_hint_fastest;\n"
/*"# cgc version 3.1.0013, build date Apr 18 2012\n"
"# command line args: -profile arbfp1 -O3 -fastmath -fastprecision\n"
"# source file: fxaa_pp.cg\n"
"#vendor NVIDIA Corporation\n"
"#version 3.1.0.13\n"
"#profile arbfp1\n"
"#program fxaa_pp\n"
"#semantic fxaa_pp.fxaaQualityRcpFrame\n"
"#semantic fxaa_pp.fxaaQualitySubpix\n"
"#semantic fxaa_pp.fxaaQualityEdgeThreshold\n"
"#semantic fxaa_pp.fxaaQualityEdgeThresholdMin\n"
"#semantic fxaa_pp.nlTex0 : TEX0\n"
"#var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1\n"
"#var float2 fxaaQualityRcpFrame : : c[0] : 2 : 1\n"
"#var float fxaaQualitySubpix : : c[1] : 3 : 1\n"
"#var float fxaaQualityEdgeThreshold : : c[2] : 4 : 1\n"
"#var float fxaaQualityEdgeThresholdMin : : c[3] : 5 : 1\n"
"#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1\n"
"#var float4 oCol : $vout.COLOR : COL : 7 : 1\n"
"#const c[4] = 0 -1 1 -2\n"
"#const c[5] = 2 0.5 0.25 1.5\n"
"#const c[6] = 4 12 0.083333336 3\n"*/
"PARAM c[7] = { program.env[0..3],\n"
" { 0, -1, 1, -2 },\n"
" { 2, 0.5, 0.25, 1.5 },\n"
" { 4, 12, 0.083333336, 3 } };\n"
"TEMP R0;\n"
"TEMP R1;\n"
"TEMP R2;\n"
"TEMP R3;\n"
"TEMP R4;\n"
"TEMP R5;\n"
"TEMP R6;\n"
"TEMP R7;\n"
"TEMP R8;\n"
"TEMP R9;\n"
"MOV R3.xyz, c[4];\n"
"MAD R2.zw, R3.xyyz, c[0].xyxy, fragment.texcoord[0].xyxy;\n"
"MAD R0.xy, R3, c[0], fragment.texcoord[0];\n"
"MAD R1.xy, R3.zyzw, c[0], fragment.texcoord[0];\n"
"TEX R5.y, R1, texture[0], 2D;\n"
"MAD R1.xy, R3.zxzw, c[0], fragment.texcoord[0];\n"
"ADD R0.zw, fragment.texcoord[0].xyxy, -c[0].xyxy;\n"
"TEX R4.y, R0.zwzw, texture[0], 2D;\n"
"TEX R6.y, R2.zwzw, texture[0], 2D;\n"
"TEX R8, fragment.texcoord[0], texture[0], 2D;\n"
"TEX R1.y, R1, texture[0], 2D;\n"
"TEX R0.y, R0, texture[0], 2D;\n"
"ADD R0.z, R4.y, R5.y;\n"
"MAD R1.z, R0.y, c[4].w, R0;\n"
"MAD R0.zw, R3.xyyx, c[0].xyxy, fragment.texcoord[0].xyxy;\n"
"TEX R2.y, R0.zwzw, texture[0], 2D;\n"
"ADD R0.x, R2.y, R1.y;\n"
"ABS R0.w, R1.z;\n"
"ADD R1.zw, fragment.texcoord[0].xyxy, c[0].xyxy;\n"
"TEX R7.y, R1.zwzw, texture[0], 2D;\n"
"MAD R0.z, R8.y, c[4].w, R0.x;\n"
"ABS R0.z, R0;\n"
"MAD R2.x, R0.z, c[5], R0.w;\n"
"MAD R0.zw, R3.xyxz, c[0].xyxy, fragment.texcoord[0].xyxy;\n"
"TEX R3.y, R0.zwzw, texture[0], 2D;\n"
"ADD R0.z, R0.y, R3.y;\n"
"ADD R1.x, R6.y, R7.y;\n"
"MAD R0.w, R3.y, c[4], R1.x;\n"
"MAD R1.x, R8.y, c[4].w, R0.z;\n"
"ABS R0.w, R0;\n"
"ADD R2.x, R0.w, R2;\n"
"ADD R2.w, R4.y, R6.y;\n"
"ADD R0.w, R5.y, R7.y;\n"
"ABS R1.z, R1.x;\n"
"MAD R1.x, R1.y, c[4].w, R0.w;\n"
"ABS R1.w, R1.x;\n"
"MAD R1.x, R2.y, c[4].w, R2.w;\n"
"MAD R1.z, R1, c[5].x, R1.w;\n"
"ABS R1.x, R1;\n"
"ADD R1.x, R1, R1.z;\n"
"SGE R4.x, R1, R2;\n"
"MAX R1.x, R3.y, R8.y;\n"
"MAX R1.z, R1.y, R1.x;\n"
"MAX R1.x, R0.y, R2.y;\n"
"MAX R1.x, R1, R1.z;\n"
"MIN R1.z, R3.y, R8.y;\n"
"MIN R1.w, R1.y, R1.z;\n"
"MIN R1.z, R0.y, R2.y;\n"
"MIN R1.z, R1, R1.w;\n"
"MUL R2.x, R1, c[2];\n"
"ADD R3.z, R1.x, -R1;\n"
"ABS R3.w, R4.x;\n"
"MAX R1.w, R2.x, c[3].x;\n"
"ADD R2.z, R3, -R1.w;\n"
"CMP R2.x, R2.z, c[4], c[4].z;\n"
"CMP R1.x, -R3.w, c[4], c[4].z;\n"
"MUL R3.w, R2.x, R1.x;\n"
"CMP R1.z, -R3.w, R1.y, R3.y;\n"
"ADD R1.y, -R8, R1.z;\n"
"CMP R1.w, -R3, R2.y, R0.y;\n"
"ADD R0.y, -R8, R1.w;\n"
"MUL R4.x, R2, R4;\n"
"CMP R3.y, -R3.w, c[0], R3.x;\n"
"ABS R4.w, R1.y;\n"
"ABS R4.z, R0.y;\n"
"SGE R0.y, R4.z, R4.w;\n"
"MUL R1.y, R2.x, R0;\n"
"ABS R0.y, R0;\n"
"CMP R4.y, -R0, c[4].x, c[4].z;\n"
"ABS R0.y, R1.x;\n"
"CMP R0.y, -R0, c[4].x, c[4].z;\n"
"MUL R1.x, R2, R0.y;\n"
"CMP R2.y, -R4.x, c[0], c[0].x;\n"
"CMP R2.y, -R1, -R2, R2;\n"
"MAD R1.y, R2, c[5], fragment.texcoord[0];\n"
"CMP R5.z, -R4.x, R1.y, fragment.texcoord[0].y;\n"
"ADD R5.y, R5.z, -R3;\n"
"MAD R0.y, R2, c[5], fragment.texcoord[0].x;\n"
"CMP R3.x, -R1, c[0], R3;\n"
"CMP R6.x, -R3.w, R0.y, fragment.texcoord[0];\n"
"ADD R5.w, R5.z, R3.y;\n"
"ADD R1.x, R6, -R3;\n"
"MOV R1.y, R5;\n"
"TEX R0.y, R1, texture[0], 2D;\n"
"MUL R1.y, R2.x, R4;\n"
"ADD R0.x, R0.z, R0;\n"
"ADD R0.w, R2, R0;\n"
"MAD R0.z, R0.x, c[5].x, R0.w;\n"
"ADD R1.w, R8.y, R1;\n"
"ADD R1.z, R8.y, R1;\n"
"CMP R4.y, -R1, R1.z, R1.w;\n"
"ADD R1.z, R6.x, R3.x;\n"
"MAD R5.x, -R4.y, c[5].y, R0.y;\n"
"MOV R1.w, R5;\n"
"TEX R0.y, R1.zwzw, texture[0], 2D;\n"
"MAX R1.w, R4.z, R4;\n"
"MAD R1.y, -R4, c[5], R0;\n"
"MUL R4.z, R1.w, c[5];\n"
"ABS R0.y, R1;\n"
"SGE R1.w, R0.y, R4.z;\n"
"ABS R6.y, R5.x;\n"
"SGE R0.y, R6, R4.z;\n"
"ABS R1.w, R1;\n"
"CMP R6.y, -R1.w, c[4].x, c[4].z;\n"
"ABS R0.y, R0;\n"
"CMP R5.z, -R0.y, c[4].x, c[4];\n"
"ADD_SAT R0.y, R5.z, R6;\n"
"MUL R4.w, R2.x, R0.y;\n"
"MUL R0.y, R2.x, R6;\n"
"MAD R1.w, R3.y, c[5], R5;\n"
"CMP R6.x, -R0.y, R1.w, R5.w;\n"
"MAD R6.z, R3.x, c[5].w, R1;\n"
"CMP R1.z, -R0.y, R6, R1;\n"
"MOV R1.w, R6.x;\n"
"TEX R0.y, R1.zwzw, texture[0], 2D;\n"
"MUL R1.w, R4, R6.y;\n"
"CMP R6.y, -R1.w, R0, R1;\n"
"MUL R0.y, R2.x, R5.z;\n"
"MAD R1.y, -R3, c[5].w, R5;\n"
"CMP R5.w, -R0.y, R1.y, R5.y;\n"
"MAD R6.z, -R3.x, c[5].w, R1.x;\n"
"CMP R1.x, -R0.y, R6.z, R1;\n"
"MOV R1.y, R5.w;\n"
"TEX R0.y, R1, texture[0], 2D;\n"
"MUL R5.y, R4.w, R5.z;\n"
"CMP R0.y, -R5, R0, R5.x;\n"
"MAD R5.x, -R4.y, c[5].y, R0.y;\n"
"CMP R5.z, -R5.y, R5.x, R0.y;\n"
"MAD R1.y, -R4, c[5], R6;\n"
"CMP R1.y, -R1.w, R1, R6;\n"
"ABS R1.w, R1.y;\n"
"SGE R1.w, R1, R4.z;\n"
"ABS R0.y, R5.z;\n"
"SGE R0.y, R0, R4.z;\n"
"ABS R1.w, R1;\n"
"CMP R6.y, -R1.w, c[4].x, c[4].z;\n"
"ABS R0.y, R0;\n"
"CMP R5.y, -R0, c[4].x, c[4].z;\n"
"ADD_SAT R0.y, R5, R6;\n"
"MUL R5.x, R4.w, R0.y;\n"
"MUL R0.y, R4.w, R6;\n"
"MAD R1.w, R3.y, c[5].x, R6.x;\n"
"CMP R6.x, -R0.y, R1.w, R6;\n"
"MAD R6.z, R3.x, c[5].x, R1;\n"
"CMP R1.z, -R0.y, R6, R1;\n"
"MOV R1.w, R6.x;\n"
"TEX R0.y, R1.zwzw, texture[0], 2D;\n"
"MUL R1.w, R5.x, R6.y;\n"
"CMP R6.y, -R1.w, R0, R1;\n"
"MUL R0.y, R4.w, R5;\n"
"MAD R1.y, -R3, c[5].x, R5.w;\n"
"CMP R4.w, -R0.y, R1.y, R5;\n"
"MAD R6.z, -R3.x, c[5].x, R1.x;\n"
"CMP R1.x, -R0.y, R6.z, R1;\n"
"MOV R1.y, R4.w;\n"
"TEX R0.y, R1, texture[0], 2D;\n"
"MUL R5.y, R5.x, R5;\n"
"CMP R0.y, -R5, R0, R5.z;\n"
"MAD R5.z, -R4.y, c[5].y, R0.y;\n"
"CMP R5.w, -R5.y, R5.z, R0.y;\n"
"MAD R1.y, -R4, c[5], R6;\n"
"CMP R1.y, -R1.w, R1, R6;\n"
"ABS R1.w, R1.y;\n"
"SGE R1.w, R1, R4.z;\n"
"ABS R1.w, R1;\n"
"CMP R6.y, -R1.w, c[4].x, c[4].z;\n"
"ABS R0.y, R5.w;\n"
"SGE R0.y, R0, R4.z;\n"
"ABS R0.y, R0;\n"
"CMP R5.y, -R0, c[4].x, c[4].z;\n"
"ADD_SAT R0.y, R5, R6;\n"
"MUL R5.z, R5.x, R0.y;\n"
"MUL R0.y, R5.x, R6;\n"
"MAD R1.w, R3.y, c[6].x, R6.x;\n"
"CMP R6.x, -R0.y, R1.w, R6;\n"
"MAD R6.z, R3.x, c[6].x, R1;\n"
"CMP R1.z, -R0.y, R6, R1;\n"
"MOV R1.w, R6.x;\n"
"TEX R0.y, R1.zwzw, texture[0], 2D;\n"
"MUL R1.w, R5.z, R6.y;\n"
"CMP R6.y, -R1.w, R0, R1;\n"
"MUL R0.y, R5.x, R5;\n"
"MAD R1.y, -R3, c[6].x, R4.w;\n"
"CMP R4.w, -R0.y, R1.y, R4;\n"
"MAD R5.x, -R3, c[6], R1;\n"
"CMP R1.x, -R0.y, R5, R1;\n"
"MOV R1.y, R4.w;\n"
"TEX R0.y, R1, texture[0], 2D;\n"
"MUL R1.y, R5.z, R5;\n"
"CMP R5.x, -R1.y, R0.y, R5.w;\n"
"MAD R5.y, -R4, c[5], R5.x;\n"
"CMP R1.y, -R1, R5, R5.x;\n"
"MAD R0.y, -R4, c[5], R6;\n"
"CMP R0.y, -R1.w, R0, R6;\n"
"ABS R5.x, R0.y;\n"
"ABS R1.w, R1.y;\n"
"SGE R1.w, R1, R4.z;\n"
"SGE R5.x, R5, R4.z;\n"
"ABS R4.z, R5.x;\n"
"ABS R1.w, R1;\n"
"CMP R4.z, -R4, c[4].x, c[4];\n"
"CMP R1.w, -R1, c[4].x, c[4].z;\n"
"MUL R4.z, R5, R4;\n"
"MAD R5.y, R3.x, c[6], R1.z;\n"
"CMP R5.y, -R4.z, R5, R1.z;\n"
"MAD R5.x, R3.y, c[6].y, R6;\n"
"CMP R1.z, -R4, R5.x, R6.x;\n"
"MUL R1.w, R5.z, R1;\n"
"ADD R4.z, -fragment.texcoord[0].x, R5.y;\n"
"ADD R1.z, -fragment.texcoord[0].y, R1;\n"
"CMP R1.z, -R3.w, R1, R4;\n"
"MAD R4.z, -R3.x, c[6].y, R1.x;\n"
"MAD R3.x, -R3.y, c[6].y, R4.w;\n"
"CMP R3.y, -R1.w, R4.z, R1.x;\n"
"CMP R1.x, -R1.w, R3, R4.w;\n"
"ADD R1.w, fragment.texcoord[0].x, -R3.y;\n"
"ADD R1.x, fragment.texcoord[0].y, -R1;\n"
"CMP R1.x, -R3.w, R1, R1.w;\n"
"SLT R1.w, R1.x, R1.z;\n"
"ADD R3.x, R1, R1.z;\n"
"ABS R1.w, R1;\n"
"MIN R1.x, R1, R1.z;\n"
"CMP R1.w, -R1, c[4].x, c[4].z;\n"
"MUL R1.z, R2.x, R1.w;\n"
"RCP R3.x, R3.x;\n"
"MAD R1.x, R1, -R3, c[5].y;\n"
"MUL R1.w, R4.y, c[5].y;\n"
"SLT R3.x, R1.y, c[4];\n"
"SLT R1.y, R8, R1.w;\n"
"SLT R0.y, R0, c[4].x;\n"
"ADD R0.y, R0, -R1;\n"
"ADD R1.y, -R1, R3.x;\n"
"ABS R0.y, R0;\n"
"ABS R1.y, R1;\n"
"CMP R0.y, -R0, c[4].z, c[4].x;\n"
"CMP R1.y, -R1, c[4].z, c[4].x;\n"
"CMP R0.x, -R1.z, R0.y, R1.y;\n"
"MAD R0.y, R0.z, c[6].z, -R8;\n"
"ABS R0.x, R0;\n"
"CMP R0.x, -R0, c[4], c[4].z;\n"
"MUL R0.x, R2, R0;\n"
"CMP R0.x, -R0, c[4], R1;\n"
"RCP R0.z, R3.z;\n"
"ABS R0.y, R0;\n"
"MUL_SAT R0.y, R0, R0.z;\n"
"MUL R0.z, R0.y, c[4].w;\n"
"ADD R0.z, R0, c[6].w;\n"
"MUL R0.y, R0, R0;\n"
"MUL R0.y, R0.z, R0;\n"
"MUL R0.y, R0, R0;\n"
"MUL R0.y, R0, c[1].x;\n"
"MAX R0.x, R0, R0.y;\n"
"MAD R0.y, R0.x, R2, fragment.texcoord[0];\n"
"MAD R0.z, R0.x, R2.y, fragment.texcoord[0].x;\n"
"CMP R0.x, -R3.w, R0.z, fragment.texcoord[0];\n"
"CMP R0.y, -R4.x, R0, fragment.texcoord[0];\n"
"TEX R0.xyz, R0, texture[0], 2D;\n"
"CMP R1, R2.z, R8, R9;\n"
"MOV R0.w, R8.y;\n"
"CMP result.color, -R2.x, R0, R1;\n"
"END\n";
/*"# 260 instructions, 10 R-regs\n"
"\n"*/
const char *a_arbfp1_ps3 =
"!!ARBfp1.0\n"
"OPTION ARB_precision_hint_fastest;\n"
//# cgc version 3.1.0013, build date Apr 18 2012
//# command line args: -profile arbfp1 -O3 -fastmath -fastprecision
//# source file: fxaa_fp.cg
//#vendor NVIDIA Corporation
//#version 3.1.0.13
//#profile arbfp1
//#program fxaa_fp
//#semantic fxaa_fp.fxaaConsoleRcpFrameOpt
//#semantic fxaa_fp.fxaaConsoleRcpFrameOpt2
//#semantic fxaa_fp.nlTex0 : TEX0
//#var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1
//#var float4 fxaaConsolePosPos : $vin.TEXCOORD1 : TEX1 : 1 : 1
//#var float4 fxaaConsoleRcpFrameOpt : : c[0] : 2 : 1
//#var float4 fxaaConsoleRcpFrameOpt2 : : c[1] : 3 : 1
//#var sampler2D nlTex0 : TEX0 : texunit 0 : 4 : 1
//#var float4 oCol : $vout.COLOR : COL : 5 : 1
//#const c[2] = 0.125 0 -2 2
//#const c[3] = 0.001953125 0.5
"PARAM c[4] = { program.env[0..1],\n"
" { 0.125, 0, -2, 2 },\n"
" { 0.001953125, 0.5 } };\n"
"TEMP R0;\n"
"TEMP R1;\n"
"TEMP R2;\n"
"TEMP R3;\n"
"TEMP R4;\n"
"TEMP R5;\n"
"TEX R1.w, fragment.texcoord[1].zyzw, texture[0], 2D;\n"
"ADD R0.x, R1.w, c[3];\n"
"TEX R0.w, fragment.texcoord[1].xwzw, texture[0], 2D;\n"
"TEX R1.w, fragment.texcoord[1], texture[0], 2D;\n"
"ADD R0.y, -R0.x, R0.w;\n"
"ADD R0.z, R1.w, R0.y;\n"
"TEX R2.w, fragment.texcoord[1].zwzw, texture[0], 2D;\n"
"ADD R0.y, -R1.w, R0;\n"
"ADD R1.x, R2.w, R0.y;\n"
"ADD R1.y, R0.z, -R2.w;\n"
"MUL R2.xy, R1, R1;\n"
"ADD R0.y, R2.x, R2;\n"
"RSQ R0.y, R0.y;\n"
"MUL R2.xy, R0.y, R1;\n"
"MAD R3.xy, R2, c[0].zwzw, fragment.texcoord[0];\n"
"ABS R0.z, R2.y;\n"
"ABS R0.y, R2.x;\n"
"MIN R0.y, R0, R0.z;\n"
"RCP R0.y, R0.y;\n"
"MUL R1.xy, R0.y, R2;\n"
"MUL R1.xy, R1, c[2].x;\n"
"MIN R1.xy, R1, c[2].w;\n"
"TEX R4, R3, texture[0], 2D;\n"
"MAD R2.xy, -R2, c[0].zwzw, fragment.texcoord[0];\n"
"TEX R3, R2, texture[0], 2D;\n"
"ADD R3, R3, R4;\n"
"MAX R1.xy, R1, c[2].z;\n"
"MAD R2.xy, R1, c[1].zwzw, fragment.texcoord[0];\n"
"MUL R5, R3, c[3].y;\n"
"MAD R1.xy, -R1, c[1].zwzw, fragment.texcoord[0];\n"
"MIN R0.z, R0.x, R2.w;\n"
"MIN R0.y, R0.w, R1.w;\n"
"MIN R0.y, R0, R0.z;\n"
"MAX R0.z, R0.x, R2.w;\n"
"MAX R0.x, R0.w, R1.w;\n"
"MAX R0.x, R0, R0.z;\n"
"TEX R4, R2, texture[0], 2D;\n"
"TEX R3, R1, texture[0], 2D;\n"
"ADD R3, R3, R4;\n"
"MAD R3, R3, c[3].y, R5;\n"
"MUL R3, R3, c[3].y;\n"
"SLT R0.z, R0.x, R3.w;\n"
"SLT R0.x, R3.w, R0.y;\n"
"ADD_SAT R0.x, R0, R0.z;\n"
"CMP result.color, -R0.x, R5, R3;\n"
"END\n";
//# 45 instructions, 6 R-regs
const char *a_arbfp1_earlyexit =
"!!ARBfp1.0\n"
"OPTION ARB_precision_hint_fastest;\n"
//"# cgc version 3.1.0013, build date Apr 18 2012\n"
//"# command line args: -profile arbfp1\n"
//"# source file: fxaa_fp.cg\n"
//"#vendor NVIDIA Corporation\n"
//"#version 3.1.0.13\n"
//"#profile arbfp1\n"
//"#program fxaa_fp\n"
//"#semantic fxaa_fp.fxaaConsoleRcpFrameOpt\n"
//"#semantic fxaa_fp.fxaaConsoleRcpFrameOpt2\n"
//"#semantic fxaa_fp.nlTex0 : TEX0\n"
//"#var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1\n"
//"#var float4 fxaaConsolePosPos : $vin.TEXCOORD1 : TEX1 : 1 : 1\n"
//"#var float4 fxaaConsoleRcpFrameOpt : : c[0] : 2 : 1\n"
//"#var float4 fxaaConsoleRcpFrameOpt2 : : c[1] : 3 : 1\n"
//"#var sampler2D nlTex0 : TEX0 : texunit 0 : 4 : 1\n"
//"#var float4 oCol : $vout.COLOR : COL : 5 : 1\n"
//"#const c[2] = 0.125 0 8 0.001953125\n"
//"#const c[3] = -2 2 0.5\n"
"PARAM c[4] = { program.env[0..1],\n"
" { 0.125, 0, 8, 0.001953125 },\n"
" { -2, 2, 0.5 } };\n"
"TEMP R0;\n"
"TEMP R1;\n"
"TEMP R2;\n"
"TEMP R3;\n"
"TEMP R4;\n"
"TEMP R5;\n"
"TEX R0.w, fragment.texcoord[1].zyzw, texture[0], 2D;\n"
"ADD R0.x, R0.w, c[2].w;\n"
"TEX R1.w, fragment.texcoord[1].xwzw, texture[0], 2D;\n"
"TEX R0.w, fragment.texcoord[1], texture[0], 2D;\n"
"ADD R0.y, R1.w, -R0.x;\n"
"ADD R0.z, R0.w, R0.y;\n"
"TEX R2.w, fragment.texcoord[1].zwzw, texture[0], 2D;\n"
"ADD R0.y, -R0.w, R0;\n"
"ADD R1.z, -R2.w, R0;\n"
"ADD R1.x, R2.w, R0.y;\n"
"MOV R1.y, c[2];\n"
"DP3 R0.y, R1, R1;\n"
"RSQ R0.y, R0.y;\n"
"MUL R2.xy, R0.y, R1.xzzw;\n"
"MAD R3.xy, R2, c[0].zwzw, fragment.texcoord[0];\n"
"ABS R0.z, R2.y;\n"
"ABS R0.y, R2.x;\n"
"MIN R0.y, R0, R0.z;\n"
"RCP R0.y, R0.y;\n"
"MUL R1.xy, R0.y, R2;\n"
"MUL R1.xy, R1, c[2].x;\n"
"MIN R1.xy, R1, c[3].y;\n"
"MIN R0.y, R0.w, R1.w;\n"
"TEX R4, R3, texture[0], 2D;\n"
"MAD R2.xy, -R2, c[0].zwzw, fragment.texcoord[0];\n"
"TEX R3, R2, texture[0], 2D;\n"
"ADD R3, R3, R4;\n"
"MAX R1.xy, R1, c[3].x;\n"
"MAD R2.xy, R1, c[1].zwzw, fragment.texcoord[0];\n"
"MAD R1.xy, -R1, c[1].zwzw, fragment.texcoord[0];\n"
"MUL R5, R3, c[3].z;\n"
"TEX R4, R2, texture[0], 2D;\n"
"TEX R3, R1, texture[0], 2D;\n"
"MIN R0.z, R0.x, R2.w;\n"
"MIN R1.x, R0.y, R0.z;\n"
"MAX R0.y, R0.x, R2.w;\n"
"MAX R0.x, R0.w, R1.w;\n"
"MAX R2.x, R0, R0.y;\n"
"ADD R3, R3, R4;\n"
"MAD R3, R3, c[3].z, R5;\n"
"MUL R3, R3, c[3].z;\n"
"SLT R1.z, R2.x, R3.w;\n"
"SLT R1.y, R3.w, R1.x;\n"
"TEX R0, fragment.texcoord[0], texture[0], 2D;\n"
"ADD_SAT R1.y, R1, R1.z;\n"
"MIN R1.z, R0.w, R1.x;\n"
"MAX R1.x, R2, R0.w;\n"
"ADD R2.y, R1.x, -R1.z;\n"
"CMP R1, -R1.y, R5, R3;\n"
"MAD R2.x, R2.y, c[2].z, -R2;\n"
"CMP result.color, R2.x, R0, R1;\n"
"END\n";
//"# 51 instructions, 6 R-regs\n"
const char *a_ps_2_0_test_t0 =
"ps_2_x\n"
"dcl_2d s0\n"
"dcl t0.xyz\n"
"mov r0.xy, t0.xy\n"
"texld r0, r0, s0\n"
"mov oC0, r0\n";
const char *a_ps_2_0_test_avg =
"ps_2_x\n"
"dcl_2d s0\n"
"def c0, 0.25000000, 0, 0, 0\n"
"dcl t1\n"
"mov r0.xy, t1.xwzw\n"
"mov r1.xy, t1.zyzw\n"
"texld r0, r0, s0\n"
"texld r1, r1, s0\n"
"add r2, r1, r0\n"
"mov r0.xy, t1.zwzw\n"
"texld r1, t1, s0\n"
"texld r0, r0, s0\n"
"add r1, r2, r1\n"
"add r0, r1, r0\n"
"mul r0, r0, c0.x\n"
"mov oC0, r0\n";
const char *a_ps_2_0 =
"ps_2_x\n"
/*"// cgc version 3.1.0013, build date Apr 18 2012\n"
"// command line args: -profile ps_2_x -O3 -fastmath -fastprecision\n"
"// source file: fxaa_pp.cg\n"
"//vendor NVIDIA Corporation\n"
"//version 3.1.0.13\n"
"//profile ps_2_x\n"
"//program fxaa_pp\n"
"//semantic fxaa_pp.fxaaQualityRcpFrame\n"
"//semantic fxaa_pp.fxaaQualitySubpix\n"
"//semantic fxaa_pp.fxaaQualityEdgeThreshold\n"
"//semantic fxaa_pp.fxaaQualityEdgeThresholdMin\n"
"//semantic fxaa_pp.nlTex0 : TEX0\n"
"//var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1\n"
"//var float2 fxaaQualityRcpFrame : : c[0] : 2 : 1\n"
"//var float fxaaQualitySubpix : : c[1] : 3 : 1\n"
"//var float fxaaQualityEdgeThreshold : : c[2] : 4 : 1\n"
"//var float fxaaQualityEdgeThresholdMin : : c[3] : 5 : 1\n"
"//var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1\n"
"//var float4 oCol : $vout.COLOR : COL : 7 : 1\n"
"//const c[4] = 0 -1 1 -2\n"
"//const c[5] = 2 0.5 0.25 1.5\n"
"//const c[6] = 4 12 0.083333336\n"
"//const c[7] = -2 3\n"*/
"dcl_2d s0\n"
"def c4, 0.00000000, -1.00000000, 1.00000000, -2.00000000\n"
"def c5, 2.00000000, 0.50000000, 0.25000000, 1.50000000\n"
"def c6, 4.00000000, 12.00000000, 0.08333334, 0\n"
"def c7, -2.00000000, 3.00000000, 0, 0\n"
"dcl t0.xy\n"
"mov r0.zw, c0.xyxy\n"
"mad r3.xy, c4.zxzw, r0.zwzw, t0\n"
"texld r7, r3, s0\n"
"texld r1, t0, s0\n"
"mov r0.xy, c0\n"
"mad r0.xy, c4.yxzw, r0, t0\n"
"texld r8, r0, s0\n"
"mov r0.xy, c0\n"
"mad r0.xy, c4, r0, t0\n"
"texld r9, r0, s0\n"
"add r0.xy, t0, -c0\n"
"texld r5, r0, s0\n"
"mov r3.xy, c0\n"
"mad r3.xy, c4.zyzw, r3, t0\n"
"texld r3, r3, s0\n"
"add r7.x, r8.y, r7.y\n"
"mad r0.z, r1.y, c4.w, r7.x\n"
"add r0.x, r5.y, r3.y\n"
"mad r0.w, r9.y, c4, r0.x\n"
"mov r0.xy, c0\n"
"mad r0.xy, c4.xzzw, r0, t0\n"
"texld r6, r0, s0\n"
"add r5.x, r9.y, r6.y\n"
"abs r0.z, r0\n"
"abs r0.w, r0\n"
"mad r3.x, r0.z, c5, r0.w\n"
"mov r0.zw, c0.xyxy\n"
"mad r4.xy, c4.yzzw, r0.zwzw, t0\n"
"texld r4, r4, s0\n"
"add r0.xy, t0, c0\n"
"texld r0, r0, s0\n"
"add r4.x, r5.y, r4.y\n"
"add r5.y, r3, r0\n"
"add r0.x, r4.y, r0.y\n"
"mad r0.x, r6.y, c4.w, r0\n"
"abs r0.x, r0\n"
"add r0.w, r0.x, r3.x\n"
"mad r0.x, r8.y, c4.w, r4\n"
"mad r0.z, r7.y, c4.w, r5.y\n"
"mad r0.y, r1, c4.w, r5.x\n"
"abs r0.z, r0\n"
"abs r0.y, r0\n"
"mad r0.y, r0, c5.x, r0.z\n"
"abs r0.x, r0\n"
"add r0.x, r0, r0.y\n"
"add r0.x, r0, -r0.w\n"
"cmp r3.y, r0.x, c4.z, c4.x\n"
"max r0.y, r6, r1\n"
"max r0.z, r7.y, r0.y\n"
"max r0.y, r9, r8\n"
"max r0.y, r0, r0.z\n"
"min r0.z, r6.y, r1.y\n"
"min r0.w, r7.y, r0.z\n"
"min r0.z, r9.y, r8.y\n"
"min r0.z, r0, r0.w\n"
"mul r3.x, r0.y, c2\n"
"abs_pp r0.x, r3.y\n"
"add r4.y, r0, -r0.z\n"
"max r0.w, r3.x, c3.x\n"
"add r4.z, r4.y, -r0.w\n"
"cmp_pp r4.w, r4.z, c4.z, c4.x\n"
"mul_pp r5.w, r4, r3.y\n"
"cmp_pp r0.y, -r0.x, c4.z, c4.x\n"
"mul_pp r5.z, r4.w, r0.y\n"
"cmp_pp r3.x, -r0, c4, c4.z\n"
"cmp r6.w, -r5.z, r6.y, r7.y\n"
"cmp r7.w, -r5.z, r9.y, r8.y\n"
"add r0.z, -r1.y, r6.w\n"
"add r0.y, -r1, r7.w\n"
"abs r9.z, r0\n"
"abs r7.y, r0\n"
"add r0.y, r7, -r9.z\n"
"cmp r0.y, r0, c4.z, c4.x\n"
"max r7.y, r7, r9.z\n"
"mul_pp r0.z, r4.w, r0.y\n"
"cmp r0.w, -r5, c0.x, c0.y\n"
"cmp r6.x, -r0.z, r0.w, -r0.w\n"
"mov r0.z, c0.y\n"
"cmp r6.y, -r5.z, c4.x, r0.z\n"
"mad r0.w, r6.x, c5.y, t0.y\n"
"cmp r0.z, -r5.w, t0.y, r0.w\n"
"add r8.z, r0, r6.y\n"
"add r7.z, r0, -r6.y\n"
"mov r9.y, r7.z\n"
"mov r8.y, r8.z\n"
"mad r0.w, r6.x, c5.y, t0.x\n"
"mov r0.x, c0\n"
"mul_pp r3.x, r4.w, r3\n"
"cmp r6.z, -r3.x, c4.x, r0.x\n"
"cmp r0.x, -r5.z, t0, r0.w\n"
"add r9.x, r0, -r6.z\n"
"texld r3, r9, s0\n"
"add r8.x, r0, r6.z\n"
"abs_pp r3.x, r0.y\n"
"texld r0, r8, s0\n"
"cmp_pp r0.x, -r3, c4.z, c4\n"
"add r0.w, r1.y, r6\n"
"add r0.z, r1.y, r7.w\n"
"mul_pp r0.x, r4.w, r0\n"
"cmp r6.w, -r0.x, r0.z, r0\n"
"mad r7.w, -r6, c5.y, r0.y\n"
"mad r8.w, -r6, c5.y, r3.y\n"
"abs r0.y, r7.w\n"
"abs r0.x, r8.w\n"
"mad r0.x, -r7.y, c5.z, r0\n"
"mad r0.y, -r7, c5.z, r0\n"
"cmp r0.x, r0, c4.z, c4\n"
"abs_pp r0.x, r0\n"
"cmp_pp r9.z, -r0.x, c4, c4.x\n"
"cmp r0.y, r0, c4.z, c4.x\n"
"abs_pp r0.y, r0\n"
"cmp_pp r9.w, -r0.y, c4.z, c4.x\n"
"mul_pp r0.x, r4.w, r9.z\n"
"mad r0.y, -r6, c5.w, r7.z\n"
"cmp r7.z, -r0.x, r7, r0.y\n"
"mad r0.z, -r6, c5.w, r9.x\n"
"cmp r9.x, -r0, r9, r0.z\n"
"mov r9.y, r7.z\n"
"texld r3, r9, s0\n"
"add_pp_sat r3.z, r9, r9.w\n"
"mul_pp r0.x, r4.w, r9.w\n"
"mad r0.y, r6, c5.w, r8.z\n"
"cmp r3.x, -r0, r8.z, r0.y\n"
"mad r0.z, r6, c5.w, r8.x\n"
"mul_pp r8.z, r4.w, r3\n"
"cmp r8.x, -r0, r8, r0.z\n"
"mov r8.y, r3.x\n"
"texld r0, r8, s0\n"
"mul_pp r0.w, r8.z, r9\n"
"cmp r3.z, -r0.w, r7.w, r0.y\n"
"mul_pp r0.x, r8.z, r9.z\n"
"cmp r0.y, -r0.x, r8.w, r3\n"
"mad r0.z, -r6.w, c5.y, r0.y\n"
"cmp r8.w, -r0.x, r0.y, r0.z\n"
"mad r3.y, -r6.w, c5, r3.z\n"
"cmp r9.w, -r0, r3.z, r3.y\n"
"abs r0.y, r9.w\n"
"abs r0.x, r8.w\n"
"mad r0.y, -r7, c5.z, r0\n"
"mad r0.x, -r7.y, c5.z, r0\n"
"cmp r0.y, r0, c4.z, c4.x\n"
"abs_pp r0.y, r0\n"
"cmp_pp r10.x, -r0.y, c4.z, c4\n"
"cmp r0.x, r0, c4.z, c4\n"
"abs_pp r0.x, r0\n"
"cmp_pp r9.z, -r0.x, c4, c4.x\n"
"mul_pp r0.x, r8.z, r10\n"
"mad r0.y, r6, c5.x, r3.x\n"
"cmp r7.w, -r0.x, r3.x, r0.y\n"
"mad r0.z, r6, c5.x, r8.x\n"
"cmp r8.x, -r0, r8, r0.z\n"
"mov r8.y, r7.w\n"
"texld r0, r8, s0\n"
"mul_pp r0.w, r8.z, r9.z\n"
"mad r3.x, -r6.z, c5, r9\n"
"mad r0.x, -r6.y, c5, r7.z\n"
"cmp r0.x, -r0.w, r7.z, r0\n"
"add_pp_sat r0.z, r9, r10.x\n"
"mul_pp r7.z, r8, r0\n"
"cmp r9.x, -r0.w, r9, r3\n"
"mov r9.y, r0.x\n"
"texld r3, r9, s0\n"
"mul_pp r0.z, r7, r9\n"
"cmp r0.w, -r0.z, r8, r3.y\n"
"mul_pp r3.x, r7.z, r10\n"
"cmp r3.y, -r3.x, r9.w, r0\n"
"mad r0.y, -r6.w, c5, r0.w\n"
"cmp r8.z, -r0, r0.w, r0.y\n"
"mad r3.z, -r6.w, c5.y, r3.y\n"
"cmp r9.z, -r3.x, r3.y, r3\n"
"abs r0.y, r8.z\n"
"abs r0.z, r9\n"
"mad r0.y, -r7, c5.z, r0\n"
"mad r0.z, -r7.y, c5, r0\n"
"cmp r0.y, r0, c4.z, c4.x\n"
"abs_pp r0.y, r0\n"
"cmp_pp r8.w, -r0.y, c4.z, c4.x\n"
"cmp r0.z, r0, c4, c4.x\n"
"abs_pp r0.z, r0\n"
"cmp_pp r9.w, -r0.z, c4.z, c4.x\n"
"mul_pp r0.y, r7.z, r8.w\n"
"mad r0.z, -r6.y, c6.x, r0.x\n"
"cmp r10.x, -r0.y, r0, r0.z\n"
"mad r0.w, -r6.z, c6.x, r9.x\n"
"cmp r9.x, -r0.y, r9, r0.w\n"
"mov r9.y, r10.x\n"
"texld r3, r9, s0\n"
"mul_pp r0.x, r7.z, r9.w\n"
"mad r0.z, r6, c6.x, r8.x\n"
"mad r0.y, r6, c6.x, r7.w\n"
"cmp r3.x, -r0, r7.w, r0.y\n"
"cmp r8.x, -r0, r8, r0.z\n"
"mov r8.y, r3.x\n"
"texld r0, r8, s0\n"
"add_pp_sat r3.z, r8.w, r9.w\n"
"mul_pp r0.x, r7.z, r3.z\n"
"mul_pp r3.z, r0.x, r9.w\n"
"cmp r0.y, -r3.z, r9.z, r0\n"
"mul_pp r0.z, r0.x, r8.w\n"
"cmp r0.w, -r0.z, r8.z, r3.y\n"
"mad r3.w, -r6, c5.y, r0.y\n"
"cmp r0.y, -r3.z, r0, r3.w\n"
"mad r3.y, -r6.w, c5, r0.w\n"
"cmp r0.z, -r0, r0.w, r3.y\n"
"abs r3.y, r0\n"
"abs r0.w, r0.z\n"
"mad r3.y, -r7, c5.z, r3\n"
"mad r0.w, -r7.y, c5.z, r0\n"
"cmp r3.y, r3, c4.z, c4.x\n"
"abs_pp r3.y, r3\n"
"cmp r0.w, r0, c4.z, c4.x\n"
"cmp_pp r3.z, -r3.y, c4, c4.x\n"
"abs_pp r0.w, r0\n"
"cmp_pp r3.y, -r0.w, c4.z, c4.x\n"
"mul_pp r0.w, r0.x, r3.z\n"
"mul_pp r0.x, r0, r3.y\n"
"mad r3.w, r6.y, c6.y, r3.x\n"
"cmp r3.x, -r0.w, r3, r3.w\n"
"mad r3.z, r6, c6.y, r8.x\n"
"cmp r0.w, -r0, r8.x, r3.z\n"
"mad r3.y, -r6, c6, r10.x\n"
"cmp r3.y, -r0.x, r10.x, r3\n"
"add r3.x, -t0.y, r3\n"
"add r0.w, -t0.x, r0\n"
"cmp r0.w, -r5.z, r0, r3.x\n"
"mad r3.x, -r6.z, c6.y, r9\n"
"cmp r0.x, -r0, r9, r3\n"
"add r3.x, t0.y, -r3.y\n"
"add r0.x, t0, -r0\n"
"cmp r0.x, -r5.z, r0, r3\n"
"add r3.x, r0, -r0.w\n"
"add r3.y, r0.x, r0.w\n"
"cmp r3.x, r3, c4, c4.z\n"
"abs_pp r3.x, r3\n"
"min r0.x, r0, r0.w\n"
"cmp_pp r3.x, -r3, c4.z, c4\n"
"mul_pp r0.w, r4, r3.x\n"
"rcp r3.y, r3.y\n"
"mad r0.x, r0, -r3.y, c5.y\n"
"cmp r3.y, r0, c4.x, c4.z\n"
"mad r3.x, -r6.w, c5.y, r1.y\n"
"cmp r3.x, r3, c4, c4.z\n"
"cmp r0.y, r0.z, c4.x, c4.z\n"
"add_pp r0.z, -r3.x, r3.y\n"
"add_pp r0.y, r0, -r3.x\n"
"abs_pp r0.y, r0\n"
"abs_pp r0.z, r0\n"
"cmp_pp r0.z, -r0, c4.x, c4\n"
"cmp_pp r0.y, -r0, c4.x, c4.z\n"
"cmp_pp r0.y, -r0.w, r0, r0.z\n"
"abs_pp r0.y, r0\n"
"cmp_pp r0.y, -r0, c4.z, c4.x\n"
"mul_pp r0.y, r4.w, r0\n"
"rcp r0.w, r4.y\n"
"cmp r0.x, -r0.y, r0, c4\n"
"add r3.y, r4.x, r5\n"
"add r3.x, r5, r7\n"
"mad r3.x, r3, c5, r3.y\n"
"mad r0.z, r3.x, c6, -r1.y\n"
"abs r0.z, r0\n"
"mul_sat r0.z, r0, r0.w\n"
"mul r0.w, r0.z, r0.z\n"
"mad r0.z, r0, c7.x, c7.y\n"
"mul r0.z, r0, r0.w\n"
"mul r0.z, r0, r0\n"
"mul r0.z, r0, c1.x\n"
"max r0.x, r0, r0.z\n"
"mad r0.y, r0.x, r6.x, t0\n"
"mad r0.z, r0.x, r6.x, t0.x\n"
"cmp r0.x, -r5.z, t0, r0.z\n"
"cmp r0.y, -r5.w, t0, r0\n"
"texld r0, r0, s0\n"
"mov r0.w, r1.y\n"
"cmp r1, r4.z, r2, r1\n"
"cmp r0, -r4.w, r1, r0\n"
"mov oC0, r0\n";
const char *a_ps_2_0_ps3 =
"ps_2_0\n"
// cgc version 3.1.0013, build date Apr 18 2012
// command line args: -profile ps_2_0 -O3 -fastmath -fastprecision
// source file: fxaa_pp.cg
//vendor NVIDIA Corporation
//version 3.1.0.13
//profile ps_2_0
//program fxaa_pp
//semantic fxaa_pp.fxaaConsoleRcpFrameOpt
//semantic fxaa_pp.fxaaConsoleRcpFrameOpt2
//semantic fxaa_pp.nlTex0 : TEX0
//var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1
//var float4 fxaaConsolePosPos : $vin.TEXCOORD1 : TEX1 : 1 : 1
//var float4 fxaaConsoleRcpFrameOpt : : c[0] : 2 : 1
//var float4 fxaaConsoleRcpFrameOpt2 : : c[1] : 3 : 1
//var sampler2D nlTex0 : TEX0 : texunit 0 : 4 : 1
//var float4 oCol : $vout.COLOR : COL : 5 : 1
//const c[2] = 0.001953125 0.125 2 -2
//const c[3] = 0.5 0 1
"dcl_2d s0\n"
"def c2, 0.00195313, 0.12500000, 2.00000000, -2.00000000\n"
"def c3, 0.50000000, 0.00000000, 1.00000000, 0\n"
"dcl t1\n"
"dcl t0.xy\n"
"texld r5, t1, s0\n"
"mov r1.y, t1.w\n"
"mov r1.x, t1.z\n"
"mov r2.xy, r1\n"
"mov r0.y, t1.w\n"
"mov r0.x, t1\n"
"mov r1.y, t1\n"
"mov r1.x, t1.z\n"
"texld r1, r1, s0\n"
"texld r0, r0, s0\n"
"texld r6, r2, s0\n"
"add r0.x, r1.w, c2\n"
"add r2.x, -r0, r0.w\n"
"add r1.x, r5.w, r2\n"
"add r2.z, r1.x, -r6.w\n"
"add r2.x, -r5.w, r2\n"
"add r2.x, r6.w, r2\n"
"mov r3.x, r2\n"
"mov r3.y, r2.z\n"
"mov r2.y, r2.z\n"
"mov r1.y, r2.z\n"
"mov r1.x, r2\n"
"mul r1.xy, r3, r1\n"
"add r1.x, r1, r1.y\n"
"rsq r1.x, r1.x\n"
"mul r4.xy, r1.x, r2\n"
"abs r2.x, r4.y\n"
"abs r1.x, r4\n"
"min r1.x, r1, r2\n"
"rcp r1.x, r1.x\n"
"mul r1.xy, r1.x, r4\n"
"mul r1.xy, r1, c2.y\n"
"min r1.xy, r1, c2.z\n"
"max r2.xy, r1, c2.w\n"
"mov r1.y, c1.w\n"
"mov r1.x, c1.z\n"
"mad r3.xy, r2, r1, t0\n"
"mov r1.y, c1.w\n"
"mov r1.x, c1.z\n"
"mad r5.xy, -r2, r1, t0\n"
"mov r1.y, c0.w\n"
"mov r1.x, c0.z\n"
"mad r2.xy, -r4, r1, t0\n"
"mov r1.y, c0.w\n"
"mov r1.x, c0.z\n"
"mad r1.xy, r4, r1, t0\n"
"texld r4, r5, s0\n"
"texld r3, r3, s0\n"
"texld r1, r1, s0\n"
"texld r2, r2, s0\n"
"add r1, r2, r1\n"
"mul r2, r1, c3.x\n"
"add r1, r4, r3\n"
"max r3.x, r0, r6.w\n"
"mad r1, r1, c3.x, r2\n"
"mul r4, r1, c3.x\n"
"max r1.x, r0.w, r5.w\n"
"max r1.x, r1, r3\n"
"add r1.x, -r4.w, r1\n"
"min r3.x, r0.w, r5.w\n"
"min r0.x, r0, r6.w\n"
"min r0.x, r3, r0\n"
"add r0.x, r4.w, -r0\n"
"cmp r1.x, r1, c3.y, c3.z\n"
"cmp r0.x, r0, c3.y, c3.z\n"
"add_pp_sat r0.x, r0, r1\n"
"cmp r0, -r0.x, r4, r2\n"
"mov oC0, r0\n";
const char *a_ps_2_0_earlyexit =
"ps_2_x\n"
// cgc version 3.1.0013, build date Apr 18 2012
// command line args: -profile ps_2_x
// source file: fxaa_fp.cg
//vendor NVIDIA Corporation
//version 3.1.0.13
//profile ps_2_x
//program fxaa_fp
//semantic fxaa_fp.fxaaConsoleRcpFrameOpt
//semantic fxaa_fp.fxaaConsoleRcpFrameOpt2
//semantic fxaa_fp.nlTex0 : TEX0
//var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1
//var float4 fxaaConsolePosPos : $vin.TEXCOORD1 : TEX1 : 1 : 1
//var float4 fxaaConsoleRcpFrameOpt : : c[0] : 2 : 1
//var float4 fxaaConsoleRcpFrameOpt2 : : c[1] : 3 : 1
//var sampler2D nlTex0 : TEX0 : texunit 0 : 4 : 1
//var float4 oCol : $vout.COLOR : COL : 5 : 1
//const c[2] = 0.001953125 0 0.125 2
//const c[3] = -2 0.5 0 1
//const c[4] = 8
"dcl_2d s0\n"
"def c2, 0.00195313, 0.00000000, 0.12500000, 2.00000000\n"
"def c3, -2.00000000, 0.50000000, 0.00000000, 1.00000000\n"
"def c4, 8.00000000, 0, 0, 0\n"
"dcl t1\n"
"dcl t0.xy\n"
"mov r0.xy, t1.zyzw\n"
"texld r0, r0, s0\n"
"mov r0.xy, t1.xwzw\n"
"texld r5, t1, s0\n"
"texld r4, r0, s0\n"
"add r4.x, r0.w, c2\n"
"mov r0.xy, t1.zwzw\n"
"texld r3, r0, s0\n"
"add r0.w, r4, -r4.x\n"
"add r0.x, r5.w, r0.w\n"
"add r0.z, -r3.w, r0.x\n"
"add r0.x, -r5.w, r0.w\n"
"add r0.x, r3.w, r0\n"
"mov r0.y, c2\n"
"dp3 r0.y, r0, r0\n"
"rsq r0.y, r0.y\n"
"mul r0.zw, r0.y, r0.xyxz\n"
"mad r1.xy, -r0.zwzw, c0.zwzw, t0\n"
"texld r1, r1, s0\n"
"abs r0.y, r0.w\n"
"abs r0.x, r0.z\n"
"min r0.x, r0, r0.y\n"
"rcp r0.x, r0.x\n"
"mul r0.xy, r0.x, r0.zwzw\n"
"mul r0.xy, r0, c2.z\n"
"min r2.xy, r0, c2.w\n"
"mad r0.xy, r0.zwzw, c0.zwzw, t0\n"
"texld r0, r0, s0\n"
"add r0, r1, r0\n"
"max r1.xy, r2, c3.x\n"
"mul r2, r0, c3.y\n"
"mad r0.xy, r1, c1.zwzw, t0\n"
"mad r1.xy, -r1, c1.zwzw, t0\n"
"texld r0, r0, s0\n"
"texld r1, r1, s0\n"
"add r0, r1, r0\n"
"mad r0, r0, c3.y, r2\n"
"mul r1, r0, c3.y\n"
"min r0.y, r4.x, r3.w\n"
"min r0.x, r5.w, r4.w\n"
"min r3.y, r0.x, r0\n"
"add r0.x, -r3.y, r1.w\n"
"max r0.z, r4.x, r3.w\n"
"max r0.y, r5.w, r4.w\n"
"max r3.x, r0.y, r0.z\n"
"cmp r3.z, r0.x, c3, c3.w\n"
"add r3.w, r3.x, -r1\n"
"cmp r3.w, r3, c3.z, c3\n"
"add_pp_sat r3.z, r3, r3.w\n"
"texld r0, t0, s0\n"
"min r3.w, r0, r3.y\n"
"max r3.y, r3.x, r0.w\n"
"cmp r1, -r3.z, r1, r2\n"
"add r3.y, r3, -r3.w\n"
"mad r2.x, r3.y, c4, -r3\n"
"cmp r0, r2.x, r1, r0\n"
"mov oC0, r0\n";

View file

@ -422,6 +422,11 @@ void CParticleSystem::step(TPass pass, TAnimationTime ellapsedTime, CParticleSys
NL_PS_FUNC_MAIN(CParticleSystem_step)
CHECK_INTEGRITY
OwnerModel = &model;
if (!_CoordSystemInfo.Matrix)
{
nlwarning("3D: BUG: CParticleSystem::step -> !_CoordSystemInfo.Matrix");
return;
}
nlassert(_CoordSystemInfo.Matrix); // matrix not set for position of system
if (_UserCoordSystemInfo)
{

View file

@ -0,0 +1,162 @@
/**
* \file render_target_manager.cpp
* \brief CRenderTargetManager
* \date 2014-07-30 21:30GMT
* \author Jan Boon (Kaetemi)
* CRenderTargetManager
*/
/*
* Copyright (C) 2014 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/render_target_manager.h>
// STL includes
#include <sstream>
// 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 {
struct CRenderTargetDescInt
{
public:
// Options
uint Width;
uint Height;
bool Mode2D;
UTexture::TUploadFormat Format;
// Data
NL3D::CTextureUser *TextureUser;
NLMISC::CSmartPtr<NL3D::ITexture> TextureInterface;
bool InUse;
bool Used;
};
CRenderTargetManager::CRenderTargetManager() : m_Driver(NULL)
{
}
CRenderTargetManager::~CRenderTargetManager()
{
// Call twice to reset counters and cleanup
cleanup();
cleanup();
}
NL3D::CTextureUser *CRenderTargetManager::getRenderTarget(uint width, uint height, bool mode2D, UTexture::TUploadFormat format)
{
// Find or create a render target, short loop so no real optimization
for (std::vector<CRenderTargetDescInt *>::iterator it(m_RenderTargets.begin()), end(m_RenderTargets.end()); it != end; ++it)
{
CRenderTargetDescInt *desc = *it;
if (!desc->InUse && desc->Width == width && desc->Height == height && desc->Mode2D == mode2D && desc->Format == format)
{
desc->InUse = true;
desc->Used = true;
return desc->TextureUser;
}
}
nldebug("3D: Create new render target (%u x %u)", width, height);
NL3D::IDriver *drvInternal = (static_cast<CDriverUser *>(m_Driver))->getDriver();
CRenderTargetDescInt *desc = new CRenderTargetDescInt();
CTextureBloom *tex = new CTextureBloom(); // LOL
tex->mode2D(mode2D);
desc->TextureInterface = tex;
desc->TextureInterface->setRenderTarget(true);
desc->TextureInterface->setReleasable(false);
desc->TextureInterface->setUploadFormat((ITexture::TUploadFormat)(uint32)format);
desc->TextureInterface->resize(width, height);
desc->TextureInterface->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff);
desc->TextureInterface->setWrapS(ITexture::Clamp);
desc->TextureInterface->setWrapT(ITexture::Clamp);
drvInternal->setupTexture(*desc->TextureInterface);
desc->TextureUser = new CTextureUser(desc->TextureInterface);
nlassert(!drvInternal->isTextureRectangle(desc->TextureInterface)); // Not allowed, we only support NPOT for render targets now.
desc->Width = width;
desc->Height = height;
desc->Mode2D = mode2D;
desc->Format = format;
desc->Used = true;
desc->InUse = true;
m_RenderTargets.push_back(desc);
return desc->TextureUser;
}
void CRenderTargetManager::recycleRenderTarget(NL3D::CTextureUser *renderTarget)
{
for (std::vector<CRenderTargetDescInt *>::iterator it(m_RenderTargets.begin()), end(m_RenderTargets.end()); it != end; ++it)
{
CRenderTargetDescInt *desc = *it;
if (desc->TextureUser == renderTarget)
{
desc->InUse = false;
return;
}
}
nlerror("3D: Render target not found");
}
void CRenderTargetManager::cleanup()
{
for (sint i = 0; i < (sint)m_RenderTargets.size(); ++i)
{
CRenderTargetDescInt *desc = m_RenderTargets[i];
nlassert(!desc->InUse); // Assert for debugging, to not allow textures being carried over between frames. Optional assert
if (!desc->InUse)
{
if (!desc->Used)
{
// No longer in use
nldebug("3D: Release render target (%u x %u)", desc->Width, desc->Height);
delete desc->TextureUser;
desc->TextureUser = NULL;
desc->TextureInterface = NULL; // CSmartPtr
m_RenderTargets.erase(m_RenderTargets.begin() + i);
--i;
}
else
{
// Flag for next round
desc->Used = false;
}
}
}
}
} /* namespace NL3D */
/* end of file */

View file

@ -92,7 +92,7 @@ CRenderTrav::CRenderTrav()
// ***************************************************************************
void CRenderTrav::traverse(UScene::TRenderPart renderPart, bool newRender)
void CRenderTrav::traverse(UScene::TRenderPart renderPart, bool newRender, bool generateShadows)
{
#ifdef NL_DEBUG_RENDER_TRAV
nlwarning("Render trave begin");
@ -279,7 +279,8 @@ void CRenderTrav::traverse(UScene::TRenderPart renderPart, bool newRender)
*/
// Generate ShadowMaps
_ShadowMapManager.renderGenerate(Scene);
if (generateShadows)
_ShadowMapManager.renderGenerate(Scene);
// Render the Landscape
renderLandscapes();

View file

@ -353,28 +353,31 @@ void CScene::beginPartRender()
// ***************************************************************************
void CScene::endPartRender()
void CScene::endPartRender(bool keepTrav)
{
nlassert(_IsRendering);
// Delete model deleted during the rendering
_IsRendering = false;
uint i;
for (i=0; i<_ToDelete.size(); i++)
deleteModel (_ToDelete[i]);
_ToDelete.clear ();
// Special for SkeletonSpawnScript animation. create models spawned now
flushSSSModelRequests();
if (!keepTrav)
{
// Delete model deleted during the rendering
uint i;
for (i=0; i<_ToDelete.size(); i++)
deleteModel (_ToDelete[i]);
_ToDelete.clear ();
// Particle system handling (remove the resources of those which are too far, as their clusters may not have been parsed).
// Note that only a few of them are tested at each call
_ParticleSystemManager.refreshModels(ClipTrav.WorldFrustumPyramid, ClipTrav.CamPos);
// Special for SkeletonSpawnScript animation. create models spawned now
flushSSSModelRequests();
// Waiting Instance handling
double deltaT = _DeltaSystemTimeBetweenRender;
clamp (deltaT, 0.01, 0.1);
updateWaitingInstances(deltaT);
// Particle system handling (remove the resources of those which are too far, as their clusters may not have been parsed).
// Note that only a few of them are tested at each call
_ParticleSystemManager.refreshModels(ClipTrav.WorldFrustumPyramid, ClipTrav.CamPos);
// Waiting Instance handling
double deltaT = _DeltaSystemTimeBetweenRender;
clamp (deltaT, 0.01, 0.1);
updateWaitingInstances(deltaT);
}
// Reset profiling
_NextRenderProfile= false;
@ -555,7 +558,7 @@ void CScene::endPartRender()
// ***************************************************************************
void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass)
void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass, bool doTrav, bool keepTrav)
{
nlassert(_IsRendering);
@ -569,25 +572,31 @@ void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass)
// if first part to be rendered, do the start stuff
if (_RenderedPart == UScene::RenderNothing)
{
// update water envmap
//updateWaterEnvmap();
RenderTrav.clearWaterModelList();
_FirstFlare = NULL;
double fNewGlobalSystemTime = NLMISC::CTime::ticksToSecond(NLMISC::CTime::getPerformanceTime());
if(_GlobalSystemTime==0)
_DeltaSystemTimeBetweenRender= 0.020;
else
_DeltaSystemTimeBetweenRender= fNewGlobalSystemTime - _GlobalSystemTime;
_GlobalSystemTime = fNewGlobalSystemTime;
if (doTrav)
{
// update water envmap
//updateWaterEnvmap();
_FirstFlare = NULL;
double fNewGlobalSystemTime = NLMISC::CTime::ticksToSecond(NLMISC::CTime::getPerformanceTime());
if(_GlobalSystemTime==0)
_DeltaSystemTimeBetweenRender= 0.020;
else
_DeltaSystemTimeBetweenRender= fNewGlobalSystemTime - _GlobalSystemTime;
_GlobalSystemTime = fNewGlobalSystemTime;
}
//
++ _NumRender;
//
nlassert(CurrentCamera);
// update models.
updateModels();
// Use the camera to setup Clip / Render pass.
float left, right, bottom, top, znear, zfar;
CurrentCamera->getFrustum(left, right, bottom, top, znear, zfar);
@ -609,49 +618,67 @@ void CScene::renderPart(UScene::TRenderPart rp, bool doHrcPass)
// **** For all render traversals, traverse them (except the Hrc one), in ascending order.
if( doHrcPass )
HrcTrav.traverse();
else
HrcTrav._MovingObjects.clear();
// Set Cam World Matrix for all trav that need it
ClipTrav.setCamMatrix(CurrentCamera->getWorldMatrix());
RenderTrav.setCamMatrix (CurrentCamera->getWorldMatrix());
LoadBalancingTrav.setCamMatrix (CurrentCamera->getWorldMatrix());
// clip
ClipTrav.traverse();
// animDetail
AnimDetailTrav.traverse();
// loadBalance
LoadBalancingTrav.traverse();
//
if (_RequestParticlesAnimate)
if (doTrav)
{
_ParticleSystemManager.processAnimate(_EllapsedTime); // deals with permanently animated particle systems
_RequestParticlesAnimate = false;
//
if (_RequestParticlesAnimate)
{
_ParticleSystemManager.processAnimate(_EllapsedTime); // deals with permanently animated particle systems
_RequestParticlesAnimate = false;
}
}
// Light
LightTrav.traverse();
}
// render
RenderTrav.traverse(rp, _RenderedPart == UScene::RenderNothing);
// Always must clear shadow caster (if render did not work because of IDriver::isLost())
RenderTrav.getShadowMapManager().clearAllShadowCasters();
RenderTrav.traverse(rp, (_RenderedPart == UScene::RenderNothing), doTrav);
if (!keepTrav)
{
// Always must clear shadow caster (if render did not work because of IDriver::isLost())
RenderTrav.getShadowMapManager().clearAllShadowCasters();
}
// render flare
if (rp & UScene::RenderFlare)
{
if (_FirstFlare)
if (doTrav)
{
IDriver *drv = getDriver();
CFlareModel::updateOcclusionQueryBegin(drv);
CFlareModel *currFlare = _FirstFlare;
do
if (_FirstFlare)
{
currFlare->updateOcclusionQuery(drv);
currFlare = currFlare->Next;
IDriver *drv = getDriver();
CFlareModel::updateOcclusionQueryBegin(drv);
CFlareModel *currFlare = _FirstFlare;
do
{
currFlare->updateOcclusionQuery(drv);
currFlare = currFlare->Next;
}
while(currFlare);
CFlareModel::updateOcclusionQueryEnd(drv);
}
while(currFlare);
CFlareModel::updateOcclusionQueryEnd(drv);
}
else
{
_FirstFlare = NULL;
}
}
_RenderedPart = (UScene::TRenderPart) (_RenderedPart | rp);

View file

@ -517,7 +517,7 @@ void CSceneUser::beginPartRender()
}
// ***************************************************************************
void CSceneUser::renderPart(TRenderPart rp)
void CSceneUser::renderPart(TRenderPart rp, bool doHrcPass, bool doTrav, bool keepTrav)
{
// render the scene.
@ -526,18 +526,18 @@ void CSceneUser::renderPart(TRenderPart rp)
if(_Scene.getCam() == NULL)
nlerror("render(): try to render with no camera linked (may have been deleted)");
_Scene.renderPart(rp, true);
_Scene.renderPart(rp, doHrcPass, doTrav, keepTrav);
}
}
// ***************************************************************************
void CSceneUser::endPartRender(bool updateWaitingInstancesFlag, bool restoreMatrixContextAfterRender)
void CSceneUser::endPartRender(bool updateWaitingInstancesFlag, bool restoreMatrixContextAfterRender, bool keepTrav)
{
// render the scene.
{
NL3D_HAUTO_RENDER_SCENE_END
_Scene.endPartRender();
_Scene.endPartRender(keepTrav);
}
if (updateWaitingInstancesFlag) updateWaitingInstances();

View file

@ -0,0 +1,3 @@
cgc -entry fxaa_pp fxaa_pp.cg -profile arbfp1 -O3 -fastmath -fastprecision -o fxaa_pp_arbfp1.txt
cgc -entry fxaa_pp fxaa_pp.cg -profile ps_2_x -O3 -fastmath -fastprecision -o fxaa_pp_ps_2_0.txt
cgc -entry fxaa_vp fxaa_vp.cg -profile arbvp1 -fastmath -fastprecision -o fxaa_vp_arbvp1.txt

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,91 @@
#define FXAA_PC 1
#define FXAA_HLSL_3 1
#define FXAA_QUALITY__PRESET 12
#define FXAA_EARLY_EXIT 0
#define FXAA_GREEN_AS_LUMA 1
#define h4tex2Dlod tex2Dlod
#define half4 float4
#define half3 float3
#define half2 float2
#define half float
#include "fxaa3_11.h"
void fxaa_pp(
// Per fragment parameters
float2 pos : TEXCOORD0,
#if (FXAA_PS3 == 1)
float4 fxaaConsolePosPos : TEXCOORD1,
#endif
// Fragment program constants
#if (FXAA_PC == 1)
uniform float2 fxaaQualityRcpFrame,
uniform float fxaaQualitySubpix,
uniform float fxaaQualityEdgeThreshold,
uniform float fxaaQualityEdgeThresholdMin,
#else
uniform float4 fxaaConsoleRcpFrameOpt,
uniform float4 fxaaConsoleRcpFrameOpt2,
#endif
uniform sampler2D nlTex0 : TEX0,
// Output color
out float4 oCol : COLOR
)
{
#if (FXAA_PC == 1)
oCol = FxaaPixelShader(
pos,
nlTex0,
fxaaQualityRcpFrame,
fxaaQualitySubpix,
fxaaQualityEdgeThreshold,
fxaaQualityEdgeThresholdMin
);
#else
oCol = FxaaPixelShader(
pos,
fxaaConsolePosPos,
nlTex0,
fxaaConsoleRcpFrameOpt,
fxaaConsoleRcpFrameOpt2
);
#endif
}
/*
Have FXAA vertex shader run as a full screen triangle,
and output "pos" and "fxaaConsolePosPos"
such that inputs in the pixel shader provide,
// {xy} = center of pixel
FxaaFloat2 pos,
// {xy__} = upper left of pixel
// {__zw} = lower right of pixel
FxaaFloat4 fxaaConsolePosPos,
*/
// fxaaConsoleRcpFrameOpt:
// Only used on FXAA Console.
// This must be from a constant/uniform.
// This effects sub-pixel AA quality and inversely sharpness.
// Where N ranges between,
// N = 0.50 (default)
// N = 0.33 (sharper)
// {x___} = -N/screenWidthInPixels
// {_y__} = -N/screenHeightInPixels
// {__z_} = N/screenWidthInPixels
// {___w} = N/screenHeightInPixels
// fxaaConsoleRcpFrameOpt2:
// Only used on FXAA Console.
// Not used on 360, but used on PS3 and PC.
// This must be from a constant/uniform.
// {x___} = -2.0/screenWidthInPixels
// {_y__} = -2.0/screenHeightInPixels
// {__z_} = 2.0/screenWidthInPixels
// {___w} = 2.0/screenHeightInPixels

View file

@ -0,0 +1,300 @@
!!ARBfp1.0
OPTION ARB_precision_hint_fastest;
# cgc version 3.1.0013, build date Apr 18 2012
# command line args: -profile arbfp1 -O3 -fastmath -fastprecision
# source file: fxaa_pp.cg
#vendor NVIDIA Corporation
#version 3.1.0.13
#profile arbfp1
#program fxaa_pp
#semantic fxaa_pp.fxaaQualityRcpFrame
#semantic fxaa_pp.fxaaQualitySubpix
#semantic fxaa_pp.fxaaQualityEdgeThreshold
#semantic fxaa_pp.fxaaQualityEdgeThresholdMin
#semantic fxaa_pp.nlTex0 : TEX0
#var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1
#var float2 fxaaQualityRcpFrame : : c[0] : 1 : 1
#var float fxaaQualitySubpix : : c[1] : 2 : 1
#var float fxaaQualityEdgeThreshold : : c[2] : 3 : 1
#var float fxaaQualityEdgeThresholdMin : : c[3] : 4 : 1
#var sampler2D nlTex0 : TEX0 : texunit 0 : 5 : 1
#var float4 oCol : $vout.COLOR : COL : 6 : 1
#const c[4] = 0 -1 1 -2
#const c[5] = 2 0.5 0.25 1.5
#const c[6] = 4 12 0.083333336 3
PARAM c[7] = { program.local[0..3],
{ 0, -1, 1, -2 },
{ 2, 0.5, 0.25, 1.5 },
{ 4, 12, 0.083333336, 3 } };
TEMP R0;
TEMP R1;
TEMP R2;
TEMP R3;
TEMP R4;
TEMP R5;
TEMP R6;
TEMP R7;
TEMP R8;
TEMP R9;
MOV R3.xyz, c[4];
MAD R2.zw, R3.xyyz, c[0].xyxy, fragment.texcoord[0].xyxy;
MAD R0.xy, R3, c[0], fragment.texcoord[0];
MAD R1.xy, R3.zyzw, c[0], fragment.texcoord[0];
TEX R5.y, R1, texture[0], 2D;
MAD R1.xy, R3.zxzw, c[0], fragment.texcoord[0];
ADD R0.zw, fragment.texcoord[0].xyxy, -c[0].xyxy;
TEX R4.y, R0.zwzw, texture[0], 2D;
TEX R6.y, R2.zwzw, texture[0], 2D;
TEX R8, fragment.texcoord[0], texture[0], 2D;
TEX R1.y, R1, texture[0], 2D;
TEX R0.y, R0, texture[0], 2D;
ADD R0.z, R4.y, R5.y;
MAD R1.z, R0.y, c[4].w, R0;
MAD R0.zw, R3.xyyx, c[0].xyxy, fragment.texcoord[0].xyxy;
TEX R2.y, R0.zwzw, texture[0], 2D;
ADD R0.x, R2.y, R1.y;
ABS R0.w, R1.z;
ADD R1.zw, fragment.texcoord[0].xyxy, c[0].xyxy;
TEX R7.y, R1.zwzw, texture[0], 2D;
MAD R0.z, R8.y, c[4].w, R0.x;
ABS R0.z, R0;
MAD R2.x, R0.z, c[5], R0.w;
MAD R0.zw, R3.xyxz, c[0].xyxy, fragment.texcoord[0].xyxy;
TEX R3.y, R0.zwzw, texture[0], 2D;
ADD R0.z, R0.y, R3.y;
ADD R1.x, R6.y, R7.y;
MAD R0.w, R3.y, c[4], R1.x;
MAD R1.x, R8.y, c[4].w, R0.z;
ABS R0.w, R0;
ADD R2.x, R0.w, R2;
ADD R2.w, R4.y, R6.y;
ADD R0.w, R5.y, R7.y;
ABS R1.z, R1.x;
MAD R1.x, R1.y, c[4].w, R0.w;
ABS R1.w, R1.x;
MAD R1.x, R2.y, c[4].w, R2.w;
MAD R1.z, R1, c[5].x, R1.w;
ABS R1.x, R1;
ADD R1.x, R1, R1.z;
SGE R4.x, R1, R2;
MAX R1.x, R3.y, R8.y;
MAX R1.z, R1.y, R1.x;
MAX R1.x, R0.y, R2.y;
MAX R1.x, R1, R1.z;
MIN R1.z, R3.y, R8.y;
MIN R1.w, R1.y, R1.z;
MIN R1.z, R0.y, R2.y;
MIN R1.z, R1, R1.w;
MUL R2.x, R1, c[2];
ADD R3.z, R1.x, -R1;
ABS R3.w, R4.x;
MAX R1.w, R2.x, c[3].x;
ADD R2.z, R3, -R1.w;
CMP R2.x, R2.z, c[4], c[4].z;
CMP R1.x, -R3.w, c[4], c[4].z;
MUL R3.w, R2.x, R1.x;
CMP R1.z, -R3.w, R1.y, R3.y;
ADD R1.y, -R8, R1.z;
CMP R1.w, -R3, R2.y, R0.y;
ADD R0.y, -R8, R1.w;
MUL R4.x, R2, R4;
CMP R3.y, -R3.w, c[0], R3.x;
ABS R4.w, R1.y;
ABS R4.z, R0.y;
SGE R0.y, R4.z, R4.w;
MUL R1.y, R2.x, R0;
ABS R0.y, R0;
CMP R4.y, -R0, c[4].x, c[4].z;
ABS R0.y, R1.x;
CMP R0.y, -R0, c[4].x, c[4].z;
MUL R1.x, R2, R0.y;
CMP R2.y, -R4.x, c[0], c[0].x;
CMP R2.y, -R1, -R2, R2;
MAD R1.y, R2, c[5], fragment.texcoord[0];
CMP R5.z, -R4.x, R1.y, fragment.texcoord[0].y;
ADD R5.y, R5.z, -R3;
MAD R0.y, R2, c[5], fragment.texcoord[0].x;
CMP R3.x, -R1, c[0], R3;
CMP R6.x, -R3.w, R0.y, fragment.texcoord[0];
ADD R5.w, R5.z, R3.y;
ADD R1.x, R6, -R3;
MOV R1.y, R5;
TEX R0.y, R1, texture[0], 2D;
MUL R1.y, R2.x, R4;
ADD R0.x, R0.z, R0;
ADD R0.w, R2, R0;
MAD R0.z, R0.x, c[5].x, R0.w;
ADD R1.w, R8.y, R1;
ADD R1.z, R8.y, R1;
CMP R4.y, -R1, R1.z, R1.w;
ADD R1.z, R6.x, R3.x;
MAD R5.x, -R4.y, c[5].y, R0.y;
MOV R1.w, R5;
TEX R0.y, R1.zwzw, texture[0], 2D;
MAX R1.w, R4.z, R4;
MAD R1.y, -R4, c[5], R0;
MUL R4.z, R1.w, c[5];
ABS R0.y, R1;
SGE R1.w, R0.y, R4.z;
ABS R6.y, R5.x;
SGE R0.y, R6, R4.z;
ABS R1.w, R1;
CMP R6.y, -R1.w, c[4].x, c[4].z;
ABS R0.y, R0;
CMP R5.z, -R0.y, c[4].x, c[4];
ADD_SAT R0.y, R5.z, R6;
MUL R4.w, R2.x, R0.y;
MUL R0.y, R2.x, R6;
MAD R1.w, R3.y, c[5], R5;
CMP R6.x, -R0.y, R1.w, R5.w;
MAD R6.z, R3.x, c[5].w, R1;
CMP R1.z, -R0.y, R6, R1;
MOV R1.w, R6.x;
TEX R0.y, R1.zwzw, texture[0], 2D;
MUL R1.w, R4, R6.y;
CMP R6.y, -R1.w, R0, R1;
MUL R0.y, R2.x, R5.z;
MAD R1.y, -R3, c[5].w, R5;
CMP R5.w, -R0.y, R1.y, R5.y;
MAD R6.z, -R3.x, c[5].w, R1.x;
CMP R1.x, -R0.y, R6.z, R1;
MOV R1.y, R5.w;
TEX R0.y, R1, texture[0], 2D;
MUL R5.y, R4.w, R5.z;
CMP R0.y, -R5, R0, R5.x;
MAD R5.x, -R4.y, c[5].y, R0.y;
CMP R5.z, -R5.y, R5.x, R0.y;
MAD R1.y, -R4, c[5], R6;
CMP R1.y, -R1.w, R1, R6;
ABS R1.w, R1.y;
SGE R1.w, R1, R4.z;
ABS R0.y, R5.z;
SGE R0.y, R0, R4.z;
ABS R1.w, R1;
CMP R6.y, -R1.w, c[4].x, c[4].z;
ABS R0.y, R0;
CMP R5.y, -R0, c[4].x, c[4].z;
ADD_SAT R0.y, R5, R6;
MUL R5.x, R4.w, R0.y;
MUL R0.y, R4.w, R6;
MAD R1.w, R3.y, c[5].x, R6.x;
CMP R6.x, -R0.y, R1.w, R6;
MAD R6.z, R3.x, c[5].x, R1;
CMP R1.z, -R0.y, R6, R1;
MOV R1.w, R6.x;
TEX R0.y, R1.zwzw, texture[0], 2D;
MUL R1.w, R5.x, R6.y;
CMP R6.y, -R1.w, R0, R1;
MUL R0.y, R4.w, R5;
MAD R1.y, -R3, c[5].x, R5.w;
CMP R4.w, -R0.y, R1.y, R5;
MAD R6.z, -R3.x, c[5].x, R1.x;
CMP R1.x, -R0.y, R6.z, R1;
MOV R1.y, R4.w;
TEX R0.y, R1, texture[0], 2D;
MUL R5.y, R5.x, R5;
CMP R0.y, -R5, R0, R5.z;
MAD R5.z, -R4.y, c[5].y, R0.y;
CMP R5.w, -R5.y, R5.z, R0.y;
MAD R1.y, -R4, c[5], R6;
CMP R1.y, -R1.w, R1, R6;
ABS R1.w, R1.y;
SGE R1.w, R1, R4.z;
ABS R1.w, R1;
CMP R6.y, -R1.w, c[4].x, c[4].z;
ABS R0.y, R5.w;
SGE R0.y, R0, R4.z;
ABS R0.y, R0;
CMP R5.y, -R0, c[4].x, c[4].z;
ADD_SAT R0.y, R5, R6;
MUL R5.z, R5.x, R0.y;
MUL R0.y, R5.x, R6;
MAD R1.w, R3.y, c[6].x, R6.x;
CMP R6.x, -R0.y, R1.w, R6;
MAD R6.z, R3.x, c[6].x, R1;
CMP R1.z, -R0.y, R6, R1;
MOV R1.w, R6.x;
TEX R0.y, R1.zwzw, texture[0], 2D;
MUL R1.w, R5.z, R6.y;
CMP R6.y, -R1.w, R0, R1;
MUL R0.y, R5.x, R5;
MAD R1.y, -R3, c[6].x, R4.w;
CMP R4.w, -R0.y, R1.y, R4;
MAD R5.x, -R3, c[6], R1;
CMP R1.x, -R0.y, R5, R1;
MOV R1.y, R4.w;
TEX R0.y, R1, texture[0], 2D;
MUL R1.y, R5.z, R5;
CMP R5.x, -R1.y, R0.y, R5.w;
MAD R5.y, -R4, c[5], R5.x;
CMP R1.y, -R1, R5, R5.x;
MAD R0.y, -R4, c[5], R6;
CMP R0.y, -R1.w, R0, R6;
ABS R5.x, R0.y;
ABS R1.w, R1.y;
SGE R1.w, R1, R4.z;
SGE R5.x, R5, R4.z;
ABS R4.z, R5.x;
ABS R1.w, R1;
CMP R4.z, -R4, c[4].x, c[4];
CMP R1.w, -R1, c[4].x, c[4].z;
MUL R4.z, R5, R4;
MAD R5.y, R3.x, c[6], R1.z;
CMP R5.y, -R4.z, R5, R1.z;
MAD R5.x, R3.y, c[6].y, R6;
CMP R1.z, -R4, R5.x, R6.x;
MUL R1.w, R5.z, R1;
ADD R4.z, -fragment.texcoord[0].x, R5.y;
ADD R1.z, -fragment.texcoord[0].y, R1;
CMP R1.z, -R3.w, R1, R4;
MAD R4.z, -R3.x, c[6].y, R1.x;
MAD R3.x, -R3.y, c[6].y, R4.w;
CMP R3.y, -R1.w, R4.z, R1.x;
CMP R1.x, -R1.w, R3, R4.w;
ADD R1.w, fragment.texcoord[0].x, -R3.y;
ADD R1.x, fragment.texcoord[0].y, -R1;
CMP R1.x, -R3.w, R1, R1.w;
SLT R1.w, R1.x, R1.z;
ADD R3.x, R1, R1.z;
ABS R1.w, R1;
MIN R1.x, R1, R1.z;
CMP R1.w, -R1, c[4].x, c[4].z;
MUL R1.z, R2.x, R1.w;
RCP R3.x, R3.x;
MAD R1.x, R1, -R3, c[5].y;
MUL R1.w, R4.y, c[5].y;
SLT R3.x, R1.y, c[4];
SLT R1.y, R8, R1.w;
SLT R0.y, R0, c[4].x;
ADD R0.y, R0, -R1;
ADD R1.y, -R1, R3.x;
ABS R0.y, R0;
ABS R1.y, R1;
CMP R0.y, -R0, c[4].z, c[4].x;
CMP R1.y, -R1, c[4].z, c[4].x;
CMP R0.x, -R1.z, R0.y, R1.y;
MAD R0.y, R0.z, c[6].z, -R8;
ABS R0.x, R0;
CMP R0.x, -R0, c[4], c[4].z;
MUL R0.x, R2, R0;
CMP R0.x, -R0, c[4], R1;
RCP R0.z, R3.z;
ABS R0.y, R0;
MUL_SAT R0.y, R0, R0.z;
MUL R0.z, R0.y, c[4].w;
ADD R0.z, R0, c[6].w;
MUL R0.y, R0, R0;
MUL R0.y, R0.z, R0;
MUL R0.y, R0, R0;
MUL R0.y, R0, c[1].x;
MAX R0.x, R0, R0.y;
MAD R0.y, R0.x, R2, fragment.texcoord[0];
MAD R0.z, R0.x, R2.y, fragment.texcoord[0].x;
CMP R0.x, -R3.w, R0.z, fragment.texcoord[0];
CMP R0.y, -R4.x, R0, fragment.texcoord[0];
TEX R0.xyz, R0, texture[0], 2D;
CMP R1, R2.z, R8, R9;
MOV R0.w, R8.y;
CMP result.color, -R2.x, R0, R1;
END
# 260 instructions, 10 R-regs

View file

@ -0,0 +1,306 @@
ps_2_x
// cgc version 3.1.0013, build date Apr 18 2012
// command line args: -profile ps_2_x -O3 -fastmath -fastprecision
// source file: fxaa_pp.cg
//vendor NVIDIA Corporation
//version 3.1.0.13
//profile ps_2_x
//program fxaa_pp
//semantic fxaa_pp.fxaaQualityRcpFrame
//semantic fxaa_pp.fxaaQualitySubpix
//semantic fxaa_pp.fxaaQualityEdgeThreshold
//semantic fxaa_pp.fxaaQualityEdgeThresholdMin
//semantic fxaa_pp.nlTex0 : TEX0
//var float2 pos : $vin.TEXCOORD0 : TEX0 : 0 : 1
//var float2 fxaaQualityRcpFrame : : c[0] : 1 : 1
//var float fxaaQualitySubpix : : c[1] : 2 : 1
//var float fxaaQualityEdgeThreshold : : c[2] : 3 : 1
//var float fxaaQualityEdgeThresholdMin : : c[3] : 4 : 1
//var sampler2D nlTex0 : TEX0 : texunit 0 : 5 : 1
//var float4 oCol : $vout.COLOR : COL : 6 : 1
//const c[4] = 0 -1 1 -2
//const c[5] = 2 0.5 0.25 1.5
//const c[6] = 4 12 0.083333336
//const c[7] = -2 3
dcl_2d s0
def c4, 0.00000000, -1.00000000, 1.00000000, -2.00000000
def c5, 2.00000000, 0.50000000, 0.25000000, 1.50000000
def c6, 4.00000000, 12.00000000, 0.08333334, 0
def c7, -2.00000000, 3.00000000, 0, 0
dcl t0.xy
mov r0.zw, c0.xyxy
mad r3.xy, c4.zxzw, r0.zwzw, t0
texld r7, r3, s0
texld r1, t0, s0
mov r0.xy, c0
mad r0.xy, c4.yxzw, r0, t0
texld r8, r0, s0
mov r0.xy, c0
mad r0.xy, c4, r0, t0
texld r9, r0, s0
add r0.xy, t0, -c0
texld r5, r0, s0
mov r3.xy, c0
mad r3.xy, c4.zyzw, r3, t0
texld r3, r3, s0
add r7.x, r8.y, r7.y
mad r0.z, r1.y, c4.w, r7.x
add r0.x, r5.y, r3.y
mad r0.w, r9.y, c4, r0.x
mov r0.xy, c0
mad r0.xy, c4.xzzw, r0, t0
texld r6, r0, s0
add r5.x, r9.y, r6.y
abs r0.z, r0
abs r0.w, r0
mad r3.x, r0.z, c5, r0.w
mov r0.zw, c0.xyxy
mad r4.xy, c4.yzzw, r0.zwzw, t0
texld r4, r4, s0
add r0.xy, t0, c0
texld r0, r0, s0
add r4.x, r5.y, r4.y
add r5.y, r3, r0
add r0.x, r4.y, r0.y
mad r0.x, r6.y, c4.w, r0
abs r0.x, r0
add r0.w, r0.x, r3.x
mad r0.x, r8.y, c4.w, r4
mad r0.z, r7.y, c4.w, r5.y
mad r0.y, r1, c4.w, r5.x
abs r0.z, r0
abs r0.y, r0
mad r0.y, r0, c5.x, r0.z
abs r0.x, r0
add r0.x, r0, r0.y
add r0.x, r0, -r0.w
cmp r3.y, r0.x, c4.z, c4.x
max r0.y, r6, r1
max r0.z, r7.y, r0.y
max r0.y, r9, r8
max r0.y, r0, r0.z
min r0.z, r6.y, r1.y
min r0.w, r7.y, r0.z
min r0.z, r9.y, r8.y
min r0.z, r0, r0.w
mul r3.x, r0.y, c2
abs_pp r0.x, r3.y
add r4.y, r0, -r0.z
max r0.w, r3.x, c3.x
add r4.z, r4.y, -r0.w
cmp_pp r4.w, r4.z, c4.z, c4.x
mul_pp r5.w, r4, r3.y
cmp_pp r0.y, -r0.x, c4.z, c4.x
mul_pp r5.z, r4.w, r0.y
cmp_pp r3.x, -r0, c4, c4.z
cmp r6.w, -r5.z, r6.y, r7.y
cmp r7.w, -r5.z, r9.y, r8.y
add r0.z, -r1.y, r6.w
add r0.y, -r1, r7.w
abs r9.z, r0
abs r7.y, r0
add r0.y, r7, -r9.z
cmp r0.y, r0, c4.z, c4.x
max r7.y, r7, r9.z
mul_pp r0.z, r4.w, r0.y
cmp r0.w, -r5, c0.x, c0.y
cmp r6.x, -r0.z, r0.w, -r0.w
mov r0.z, c0.y
cmp r6.y, -r5.z, c4.x, r0.z
mad r0.w, r6.x, c5.y, t0.y
cmp r0.z, -r5.w, t0.y, r0.w
add r8.z, r0, r6.y
add r7.z, r0, -r6.y
mov r9.y, r7.z
mov r8.y, r8.z
mad r0.w, r6.x, c5.y, t0.x
mov r0.x, c0
mul_pp r3.x, r4.w, r3
cmp r6.z, -r3.x, c4.x, r0.x
cmp r0.x, -r5.z, t0, r0.w
add r9.x, r0, -r6.z
texld r3, r9, s0
add r8.x, r0, r6.z
abs_pp r3.x, r0.y
texld r0, r8, s0
cmp_pp r0.x, -r3, c4.z, c4
add r0.w, r1.y, r6
add r0.z, r1.y, r7.w
mul_pp r0.x, r4.w, r0
cmp r6.w, -r0.x, r0.z, r0
mad r7.w, -r6, c5.y, r0.y
mad r8.w, -r6, c5.y, r3.y
abs r0.y, r7.w
abs r0.x, r8.w
mad r0.x, -r7.y, c5.z, r0
mad r0.y, -r7, c5.z, r0
cmp r0.x, r0, c4.z, c4
abs_pp r0.x, r0
cmp_pp r9.z, -r0.x, c4, c4.x
cmp r0.y, r0, c4.z, c4.x
abs_pp r0.y, r0
cmp_pp r9.w, -r0.y, c4.z, c4.x
mul_pp r0.x, r4.w, r9.z
mad r0.y, -r6, c5.w, r7.z
cmp r7.z, -r0.x, r7, r0.y
mad r0.z, -r6, c5.w, r9.x
cmp r9.x, -r0, r9, r0.z
mov r9.y, r7.z
texld r3, r9, s0
add_pp_sat r3.z, r9, r9.w
mul_pp r0.x, r4.w, r9.w
mad r0.y, r6, c5.w, r8.z
cmp r3.x, -r0, r8.z, r0.y
mad r0.z, r6, c5.w, r8.x
mul_pp r8.z, r4.w, r3
cmp r8.x, -r0, r8, r0.z
mov r8.y, r3.x
texld r0, r8, s0
mul_pp r0.w, r8.z, r9
cmp r3.z, -r0.w, r7.w, r0.y
mul_pp r0.x, r8.z, r9.z
cmp r0.y, -r0.x, r8.w, r3
mad r0.z, -r6.w, c5.y, r0.y
cmp r8.w, -r0.x, r0.y, r0.z
mad r3.y, -r6.w, c5, r3.z
cmp r9.w, -r0, r3.z, r3.y
abs r0.y, r9.w
abs r0.x, r8.w
mad r0.y, -r7, c5.z, r0
mad r0.x, -r7.y, c5.z, r0
cmp r0.y, r0, c4.z, c4.x
abs_pp r0.y, r0
cmp_pp r10.x, -r0.y, c4.z, c4
cmp r0.x, r0, c4.z, c4
abs_pp r0.x, r0
cmp_pp r9.z, -r0.x, c4, c4.x
mul_pp r0.x, r8.z, r10
mad r0.y, r6, c5.x, r3.x
cmp r7.w, -r0.x, r3.x, r0.y
mad r0.z, r6, c5.x, r8.x
cmp r8.x, -r0, r8, r0.z
mov r8.y, r7.w
texld r0, r8, s0
mul_pp r0.w, r8.z, r9.z
mad r3.x, -r6.z, c5, r9
mad r0.x, -r6.y, c5, r7.z
cmp r0.x, -r0.w, r7.z, r0
add_pp_sat r0.z, r9, r10.x
mul_pp r7.z, r8, r0
cmp r9.x, -r0.w, r9, r3
mov r9.y, r0.x
texld r3, r9, s0
mul_pp r0.z, r7, r9
cmp r0.w, -r0.z, r8, r3.y
mul_pp r3.x, r7.z, r10
cmp r3.y, -r3.x, r9.w, r0
mad r0.y, -r6.w, c5, r0.w
cmp r8.z, -r0, r0.w, r0.y
mad r3.z, -r6.w, c5.y, r3.y
cmp r9.z, -r3.x, r3.y, r3
abs r0.y, r8.z
abs r0.z, r9
mad r0.y, -r7, c5.z, r0
mad r0.z, -r7.y, c5, r0
cmp r0.y, r0, c4.z, c4.x
abs_pp r0.y, r0
cmp_pp r8.w, -r0.y, c4.z, c4.x
cmp r0.z, r0, c4, c4.x
abs_pp r0.z, r0
cmp_pp r9.w, -r0.z, c4.z, c4.x
mul_pp r0.y, r7.z, r8.w
mad r0.z, -r6.y, c6.x, r0.x
cmp r10.x, -r0.y, r0, r0.z
mad r0.w, -r6.z, c6.x, r9.x
cmp r9.x, -r0.y, r9, r0.w
mov r9.y, r10.x
texld r3, r9, s0
mul_pp r0.x, r7.z, r9.w
mad r0.z, r6, c6.x, r8.x
mad r0.y, r6, c6.x, r7.w
cmp r3.x, -r0, r7.w, r0.y
cmp r8.x, -r0, r8, r0.z
mov r8.y, r3.x
texld r0, r8, s0
add_pp_sat r3.z, r8.w, r9.w
mul_pp r0.x, r7.z, r3.z
mul_pp r3.z, r0.x, r9.w
cmp r0.y, -r3.z, r9.z, r0
mul_pp r0.z, r0.x, r8.w
cmp r0.w, -r0.z, r8.z, r3.y
mad r3.w, -r6, c5.y, r0.y
cmp r0.y, -r3.z, r0, r3.w
mad r3.y, -r6.w, c5, r0.w
cmp r0.z, -r0, r0.w, r3.y
abs r3.y, r0
abs r0.w, r0.z
mad r3.y, -r7, c5.z, r3
mad r0.w, -r7.y, c5.z, r0
cmp r3.y, r3, c4.z, c4.x
abs_pp r3.y, r3
cmp r0.w, r0, c4.z, c4.x
cmp_pp r3.z, -r3.y, c4, c4.x
abs_pp r0.w, r0
cmp_pp r3.y, -r0.w, c4.z, c4.x
mul_pp r0.w, r0.x, r3.z
mul_pp r0.x, r0, r3.y
mad r3.w, r6.y, c6.y, r3.x
cmp r3.x, -r0.w, r3, r3.w
mad r3.z, r6, c6.y, r8.x
cmp r0.w, -r0, r8.x, r3.z
mad r3.y, -r6, c6, r10.x
cmp r3.y, -r0.x, r10.x, r3
add r3.x, -t0.y, r3
add r0.w, -t0.x, r0
cmp r0.w, -r5.z, r0, r3.x
mad r3.x, -r6.z, c6.y, r9
cmp r0.x, -r0, r9, r3
add r3.x, t0.y, -r3.y
add r0.x, t0, -r0
cmp r0.x, -r5.z, r0, r3
add r3.x, r0, -r0.w
add r3.y, r0.x, r0.w
cmp r3.x, r3, c4, c4.z
abs_pp r3.x, r3
min r0.x, r0, r0.w
cmp_pp r3.x, -r3, c4.z, c4
mul_pp r0.w, r4, r3.x
rcp r3.y, r3.y
mad r0.x, r0, -r3.y, c5.y
cmp r3.y, r0, c4.x, c4.z
mad r3.x, -r6.w, c5.y, r1.y
cmp r3.x, r3, c4, c4.z
cmp r0.y, r0.z, c4.x, c4.z
add_pp r0.z, -r3.x, r3.y
add_pp r0.y, r0, -r3.x
abs_pp r0.y, r0
abs_pp r0.z, r0
cmp_pp r0.z, -r0, c4.x, c4
cmp_pp r0.y, -r0, c4.x, c4.z
cmp_pp r0.y, -r0.w, r0, r0.z
abs_pp r0.y, r0
cmp_pp r0.y, -r0, c4.z, c4.x
mul_pp r0.y, r4.w, r0
rcp r0.w, r4.y
cmp r0.x, -r0.y, r0, c4
add r3.y, r4.x, r5
add r3.x, r5, r7
mad r3.x, r3, c5, r3.y
mad r0.z, r3.x, c6, -r1.y
abs r0.z, r0
mul_sat r0.z, r0, r0.w
mul r0.w, r0.z, r0.z
mad r0.z, r0, c7.x, c7.y
mul r0.z, r0, r0.w
mul r0.z, r0, r0
mul r0.z, r0, c1.x
max r0.x, r0, r0.z
mad r0.y, r0.x, r6.x, t0
mad r0.z, r0.x, r6.x, t0.x
cmp r0.x, -r5.z, t0, r0.z
cmp r0.y, -r5.w, t0, r0
texld r0, r0, s0
mov r0.w, r1.y
cmp r1, r4.z, r2, r1
cmp r0, -r4.w, r1, r0
mov oC0, r0

View file

@ -0,0 +1,20 @@
void fxaa_vp(
// Per vertex parameters
float3 position : POSITION,
float2 texCoord0 : TEXCOORD0,
// Vertex program constants
uniform float4x4 modelViewProjection,
uniform float4 fxaaConsolePosPos,
// Output position
out float4 oPosition : POSITION,
out float2 oTexCoord0 : TEXCOORD0,
out float4 oTexCoord1 : TEXCOORD1
)
{
oPosition = mul(modelViewProjection, float4(position, 0.0));
oTexCoord0 = texCoord0;
oTexCoord1 = texCoord0.xyxy + fxaaConsolePosPos;
}

View file

@ -0,0 +1,31 @@
!!ARBvp1.0
# cgc version 3.1.0013, build date Apr 18 2012
# command line args: -profile arbvp1 -fastmath -fastprecision
# source file: fxaa_vp.cg
#vendor NVIDIA Corporation
#version 3.1.0.13
#profile arbvp1
#program fxaa_vp
#semantic fxaa_vp.modelViewProjection
#semantic fxaa_vp.fxaaConsolePosPos
#var float3 position : $vin.POSITION : POSITION : 0 : 1
#var float2 texCoord0 : $vin.TEXCOORD0 : TEXCOORD0 : 1 : 1
#var float4x4 modelViewProjection : : c[1], 4 : 2 : 1
#var float4 fxaaConsolePosPos : : c[5] : 3 : 1
#var float4 oPosition : $vout.POSITION : HPOS : 4 : 1
#var float2 oTexCoord0 : $vout.TEXCOORD0 : TEX0 : 5 : 1
#var float4 oTexCoord1 : $vout.TEXCOORD1 : TEX1 : 6 : 1
#const c[0] = 0
PARAM c[6] = { { 0 },
program.local[1..5] };
TEMP R0;
MOV R0.w, c[0].x;
MOV R0.xyz, vertex.position;
DP4 result.position.w, R0, c[4];
DP4 result.position.z, R0, c[3];
DP4 result.position.y, R0, c[2];
DP4 result.position.x, R0, c[1];
ADD result.texcoord[1], vertex.texcoord[0].xyxy, c[5];
MOV result.texcoord[0].xy, vertex.texcoord[0];
END
# 8 instructions, 1 R-regs

View file

@ -0,0 +1,4 @@
Compiled shaders are embedded in the source.
Must compile and re-embed manually.
FXAA is in public domain.

View file

@ -26,7 +26,7 @@
*/
#if !FINAL_VERSION
#include <nel/misc/types_nl.h>
#include "std3d.h"
#include <nel/3d/stereo_debugger.h>
// STL includes
@ -42,6 +42,7 @@
#include <nel/3d/texture_user.h>
#include <nel/3d/driver_user.h>
#include <nel/3d/u_texture.h>
#include <nel/3d/render_target_manager.h>
using namespace std;
// using namespace NLMISC;
@ -137,8 +138,6 @@ CStereoDebugger::CStereoDebugger() : m_Driver(NULL), m_Stage(0), m_SubStage(0),
CStereoDebugger::~CStereoDebugger()
{
releaseTextures();
if (!m_Mat.empty())
{
m_Driver->deleteMaterial(m_Mat);
@ -188,8 +187,6 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver)
if (m_PixelProgram)
{
initTextures();
m_Mat = m_Driver->createMaterial();
m_Mat.initUnlit();
m_Mat.setColor(CRGBA::White);
@ -202,8 +199,6 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver)
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);
@ -216,6 +211,42 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver)
}
}
bool CStereoDebugger::attachToDisplay()
{
return false;
}
void CStereoDebugger::detachFromDisplay()
{
}
void CStereoDebugger::getTextures()
{
nlassert(!m_LeftTexU);
nlassert(!m_RightTexU);
uint32 width, height;
m_Driver->getWindowSize(width, height);
m_LeftTexU = m_Driver->getRenderTargetManager().getRenderTarget(width, height);
m_RightTexU = m_Driver->getRenderTargetManager().getRenderTarget(width, height);
NL3D::CMaterial *mat = m_Mat.getObjectPtr();
mat->setTexture(0, m_LeftTexU->getITexture());
mat->setTexture(1, m_RightTexU->getITexture());
}
void CStereoDebugger::recycleTextures()
{
nlassert(m_LeftTexU);
nlassert(m_RightTexU);
m_Mat.getObjectPtr()->setTexture(0, NULL);
m_Mat.getObjectPtr()->setTexture(1, NULL);
m_Driver->getRenderTargetManager().recycleRenderTarget(m_LeftTexU);
m_Driver->getRenderTargetManager().recycleRenderTarget(m_RightTexU);
m_LeftTexU = NULL;
m_RightTexU = NULL;
}
/*
void CStereoDebugger::releaseTextures()
{
if (!m_Mat.empty())
@ -233,7 +264,7 @@ void CStereoDebugger::releaseTextures()
m_RightTexU = NULL;
m_RightTex = NULL; // CSmartPtr
}
*//*
void CStereoDebugger::initTextures()
{
uint32 width, height;
@ -261,15 +292,15 @@ void CStereoDebugger::initTextures()
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)
@ -287,7 +318,7 @@ void CStereoDebugger::verifyTextures()
setTextures();
}
}
}
}*/
/// Gets the required screen resolution for this device
bool CStereoDebugger::getScreenResolution(uint &width, uint &height)
@ -307,6 +338,12 @@ void CStereoDebugger::getClippingFrustum(uint cid, NL3D::UCamera *camera) const
// do nothing
}
/// Get the original frustum of the camera
void CStereoDebugger::getOriginalFrustum(uint cid, NL3D::UCamera *camera) const
{
// do nothing, as we never modified it
}
/// Is there a next pass
bool CStereoDebugger::nextPass()
{
@ -388,6 +425,12 @@ bool CStereoDebugger::wantScene()
return m_Stage != 3;
}
/// The 3D scene end (after multiple wantScene)
bool CStereoDebugger::wantSceneEffects()
{
return m_Stage != 3;
}
/// Interface within the 3D scene
bool CStereoDebugger::wantInterface3D()
{
@ -402,11 +445,22 @@ bool CStereoDebugger::wantInterface2D()
return m_Stage == 3;
}
bool CStereoDebugger::isSceneFirst()
{
return m_Stage != 3;
}
bool CStereoDebugger::isSceneLast()
{
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_LeftTexU) getTextures();
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;
@ -430,14 +484,15 @@ bool CStereoDebugger::endRenderTarget()
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);
mat->setTexture(0, m_LeftTexU->getITexture());
mat->setTexture(1, m_RightTexU->getITexture());
drvInternal->activePixelProgram(m_PixelProgram);
m_Driver->drawQuad(m_QuadUV, m_Mat);
drvInternal->activePixelProgram(NULL);
m_Driver->enableFog(fogEnabled);
recycleTextures();
return true;
}

View file

@ -25,7 +25,7 @@
* <http://www.gnu.org/licenses/>.
*/
#include <nel/misc/types_nl.h>
#include "std3d.h"
#include <nel/3d/stereo_display.h>
// STL includes
@ -35,6 +35,7 @@
// Project includes
#include <nel/3d/stereo_ovr.h>
#include <nel/3d/stereo_ovr_04.h>
#include <nel/3d/stereo_libvr.h>
#include <nel/3d/stereo_debugger.h>

View file

@ -25,7 +25,7 @@
* <http://www.gnu.org/licenses/>.
*/
#include <nel/misc/types_nl.h>
#include "std3d.h"
#include <nel/3d/stereo_hmd.h>
// STL includes

View file

@ -27,7 +27,7 @@
#ifdef HAVE_LIBVR
#include <nel/misc/types_nl.h>
#include "std3d.h"
#include <nel/misc/time_nl.h>
#include <nel/3d/stereo_libvr.h>

View file

@ -41,15 +41,16 @@
* so, delete this exception statement from your version.
*/
#ifdef HAVE_LIBOVR
#ifdef HAVE_LIBOVR_02
#include <nel/misc/types_nl.h>
#include "std3d.h"
#include <nel/3d/stereo_ovr.h>
// STL includes
#include <sstream>
// External includes
#define OVR_NO_STDINT
#include <OVR.h>
// NeL includes
@ -169,7 +170,7 @@ public:
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)
CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_SceneTexture(NULL), m_GUITexture(NULL), m_PixelProgram(NULL), m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f)
{
++s_DeviceCounter;
m_DevicePtr = new CStereoOVRDevicePtr();
@ -213,9 +214,6 @@ CStereoOVR::~CStereoOVR()
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;
@ -340,7 +338,7 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver)
{
m_Driver = driver;
m_BarrelTex = new CTextureBloom(); // lol bloom
/*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);
@ -348,7 +346,7 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver)
m_BarrelTex->setWrapS(ITexture::Clamp);
m_BarrelTex->setWrapT(ITexture::Clamp);
drvInternal->setupTexture(*m_BarrelTex);
m_BarrelTexU = new CTextureUser(m_BarrelTex);
m_BarrelTexU = new CTextureUser(m_BarrelTex);*/
m_BarrelMat = m_Driver->createMaterial();
m_BarrelMat.initUnlit();
@ -361,7 +359,7 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver)
barrelMat->setZWrite(false);
barrelMat->setZFunc(CMaterial::always);
barrelMat->setDoubleSided(true);
barrelMat->setTexture(0, m_BarrelTex);
// 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);
@ -373,7 +371,7 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver)
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
// nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // not allowed
m_BarrelQuadLeft.Uv0 = CUV(0.f, 0.f);
m_BarrelQuadLeft.Uv1 = CUV(0.5f, 0.f);
@ -400,6 +398,8 @@ bool CStereoOVR::getScreenResolution(uint &width, uint &height)
void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera)
{
m_OriginalFrustum[cid] = camera->getFrustum();
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);
@ -427,6 +427,12 @@ void CStereoOVR::getClippingFrustum(uint cid, NL3D::UCamera *camera) const
camera->setFrustum(m_ClippingFrustum[cid]);
}
/// Get the original frustum of the camera
void CStereoOVR::getOriginalFrustum(uint cid, NL3D::UCamera *camera) const
{
camera->setFrustum(m_OriginalFrustum[cid]);
}
void CStereoOVR::updateCamera(uint cid, const NL3D::UCamera *camera)
{
if (camera->getFrustum().Near != m_LeftFrustum[cid].Near
@ -440,53 +446,59 @@ 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);
// nlassert(width == m_DevicePtr->HMDInfo.HResolution);
// nlassert(height == m_DevicePtr->HMDInfo.VResolution);
if (m_Driver->getPolygonMode() == UDriver::Filled)
{
switch (m_Stage)
switch (m_Stage) // Previous stage
{
case 0:
++m_Stage;
m_SubStage = 0;
// stage 1:
// (initBloom)
// clear buffer
// draw scene left
return true;
case 1:
++m_Stage;
m_Stage += 2;
m_SubStage = 0;
// stage 2:
// draw scene right
// draw interface 2d (onto render target)
return true;
case 2:
++m_Stage;
m_SubStage = 0;
// stage 3:
// (endBloom)
// draw interface 3d left
// (initBloom)
// clear buffer
// draw scene left
return true;
case 3:
++m_Stage;
m_SubStage = 0;
// stage 4:
// draw interface 3d right
// draw scene right
return true;
case 4:
++m_Stage;
m_SubStage = 0;
// stage 5:
// (endInterfacesDisplayBloom)
// draw interface 2d left
// (endBloom)
// draw interface 3d left
return true;
case 5:
++m_Stage;
m_SubStage = 0;
// stage 6:
// draw interface 2d right
// draw interface 3d right
return true;
/*case 6:
++m_Stage;
m_SubStage = 0;
// stage 7:
// (endInterfacesDisplayBloom)
// draw interface 2d left
return true;
case 7:
++m_Stage;
m_SubStage = 0;
// stage 8:
// draw interface 2d right
return true;*/
case 6:
m_Stage = 0;
m_SubStage = 0;
@ -518,26 +530,30 @@ bool CStereoOVR::nextPass()
const NL3D::CViewport &CStereoOVR::getCurrentViewport() const
{
if (m_Stage % 2) return m_LeftViewport;
if (m_Stage == 2) return m_RegularViewport;
else 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];
if (m_Stage == 2) return m_OriginalFrustum[cid];
else 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]);
if (m_Stage == 2) camera->setFrustum(m_OriginalFrustum[cid]);
else 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));
if (m_Stage == 2) { }
else 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)
@ -556,7 +572,7 @@ bool CStereoOVR::wantClear()
{
switch (m_Stage)
{
case 1:
case 3:
m_SubStage = 1;
return true;
}
@ -567,8 +583,8 @@ bool CStereoOVR::wantScene()
{
switch (m_Stage)
{
case 1:
case 2:
case 3:
case 4:
m_SubStage = 2;
return true;
}
@ -579,8 +595,8 @@ bool CStereoOVR::wantInterface3D()
{
switch (m_Stage)
{
case 3:
case 4:
case 5:
case 6:
m_SubStage = 3;
return true;
}
@ -591,37 +607,225 @@ bool CStereoOVR::wantInterface2D()
{
switch (m_Stage)
{
case 5:
case 6:
case 2:
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))
// Set GUI render target
if (m_Driver && m_Stage == 2 && (m_Driver->getPolygonMode() == UDriver::Filled))
{
static_cast<CDriverUser *>(m_Driver)->setRenderTarget(*m_BarrelTexU, 0, 0, 0, 0);
nlassert(!m_GUITexture);
uint32 width, height;
m_Driver->getWindowSize(width, height);
m_GUITexture = m_Driver->getRenderTargetManager().getRenderTarget(width, height, true, UTexture::RGBA8888);
static_cast<CDriverUser *>(m_Driver)->setRenderTarget(*m_GUITexture);
m_Driver->clearBuffers(NLMISC::CRGBA(0, 0, 0, 0));
return true;
}
// Begin 3D scene render target
if (m_Driver && m_Stage == 3 && (m_Driver->getPolygonMode() == UDriver::Filled))
{
nlassert(!m_SceneTexture);
uint32 width, height;
m_Driver->getWindowSize(width, height); // Temporary limitation, TODO: scaling!
m_SceneTexture = m_Driver->getRenderTargetManager().getRenderTarget(width, height);
static_cast<CDriverUser *>(m_Driver)->setRenderTarget(*m_SceneTexture);
return true;
}
return false;
}
void CStereoOVR::setInterfaceMatrix(const NL3D::CMatrix &matrix)
{
m_InterfaceCameraMatrix = matrix;
}
void CStereoOVR::renderGUI()
{
/*CMatrix mat;
mat.translate(m_InterfaceCameraMatrix.getPos());
CVector dir = m_InterfaceCameraMatrix.getJ();
dir.z = 0;
dir.normalize();
if (dir.y < 0)
mat.rotateZ(float(NLMISC::Pi+asin(dir.x)));
else
mat.rotateZ(float(NLMISC::Pi+NLMISC::Pi-asin(dir.x)));
m_Driver->setModelMatrix(mat);*/
m_Driver->setModelMatrix(m_InterfaceCameraMatrix);
{
NLMISC::CLine line(NLMISC::CVector(0, 5, 2), NLMISC::CVector(0, 5, 3));
NL3D::UMaterial mat = m_Driver->createMaterial();
mat.setZWrite(false);
// mat.setZFunc(UMaterial::always); // Not nice!
mat.setDoubleSided(true);
mat.setColor(NLMISC::CRGBA::Red);
mat.setBlend(false);
m_Driver->drawLine(line, mat);
m_Driver->deleteMaterial(mat);
}
{
nlassert(m_GUITexture);
NLMISC::CQuadUV quad;
NL3D::UMaterial umat = m_Driver->createMaterial();
umat.initUnlit();
umat.setColor(NLMISC::CRGBA::White);
umat.setDoubleSided(true);
umat.setBlend(true);
umat.setAlphaTest(false);
NL3D::CMaterial *mat = umat.getObjectPtr();
mat->setShader(NL3D::CMaterial::Normal);
mat->setBlendFunc(CMaterial::one, CMaterial::TBlend::invsrcalpha);
mat->setZWrite(false);
// mat->setZFunc(CMaterial::always); // Not nice
mat->setDoubleSided(true);
mat->setTexture(0, m_GUITexture->getITexture());
// user options
float scale = 1.0f;
float distance = 1.5f;
float offcenter = 0.75f;
float height = scale * distance * 2.0f;
uint32 winw, winh;
m_Driver->getWindowSize(winw, winh);
float width = height * (float)winw / (float)winh;
float bottom = -(height * 0.5f);
float top = (height * 0.5f);
NLMISC::CQuadUV quadUV;
quadUV.V0 = CVector(-(width * 0.5f), distance, -(height * 0.5f));
quadUV.V1 = CVector((width * 0.5f), distance, -(height * 0.5f));
quadUV.V2 = CVector((width * 0.5f), distance, (height * 0.5f));
quadUV.V3 = CVector(-(width * 0.5f), distance, (height * 0.5f));
quadUV.Uv0 = CUV(0.f, 0.f);
quadUV.Uv1 = CUV(1.f, 0.f);
quadUV.Uv2 = CUV(1.f, 1.f);
quadUV.Uv3 = CUV(0.f, 1.f);
const uint nbQuads = 128;
static CVertexBuffer vb;
static CIndexBuffer ib;
vb.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag);
vb.setPreferredMemory(CVertexBuffer::RAMVolatile, false);
vb.setNumVertices((nbQuads + 1) * 2);
{
CVertexBufferReadWrite vba;
vb.lock(vba);
float radius = distance + offcenter;
float relWidth = width / radius;
float quadWidth = relWidth / (float)nbQuads;
for (uint i = 0; i < nbQuads + 1; ++i)
{
uint vi0 = i * 2;
uint vi1 = vi0 + 1;
float lineH = -(relWidth * 0.5f) + quadWidth * (float)i;
float lineUV = (float)i / (float)(nbQuads);
float left = sin(lineH) * radius;
float forward = cos(lineH) * radius;
vba.setVertexCoord(vi0, left, forward - offcenter, bottom);
vba.setTexCoord(vi0, 0, lineUV, 0.0f);
vba.setVertexCoord(vi1, left, forward - offcenter, top);
vba.setTexCoord(vi1, 0, lineUV, 1.0f);
}
}
ib.setFormat(NL_DEFAULT_INDEX_BUFFER_FORMAT);
ib.setPreferredMemory(CIndexBuffer::RAMVolatile, false);
ib.setNumIndexes(nbQuads * 6);
{
CIndexBufferReadWrite iba;
ib.lock(iba);
for (uint i = 0; i < nbQuads; ++i)
{
uint ti0 = i * 2;
uint ti1 = ti0 + 1;
uint bl = ti0;
uint tl = ti0 + 1;
uint br = ti0 + 2;
uint tr = ti0 + 3;
iba.setTri(ti0 * 3, bl, tl, br);
iba.setTri(ti1 * 3, br, tl, tr);
}
}
IDriver *driver = static_cast<CDriverUser *>(m_Driver)->getDriver();
// m_Driver->setPolygonMode(UDriver::Line);
driver->activeVertexBuffer(vb);
driver->activeIndexBuffer(ib);
driver->renderTriangles(*umat.getObjectPtr(), 0, nbQuads * 2); //renderRawQuads(umat, 0, 128);
// m_Driver->setPolygonMode(UDriver::Filled);
// m_Driver->drawQuad(quadUV, umat);
m_Driver->deleteMaterial(umat);
}
}
/// Returns true if a render target was fully drawn
bool CStereoOVR::endRenderTarget()
{
// after rendering of course
// nlassert(m_SubStage > 1);
// End GUI render target
if (m_Driver && m_Stage == 2 && (m_Driver->getPolygonMode() == UDriver::Filled))
{
// End GUI render target
nlassert(m_GUITexture);
CTextureUser texNull;
(static_cast<CDriverUser *>(m_Driver))->setRenderTarget(texNull);
}
// End of 3D Interface pass left
if (m_Driver && m_Stage == 5 && (m_Driver->getPolygonMode() == UDriver::Filled))
{
// Render 2D GUI in 3D space, assume existing camera is OK
renderGUI();
}
// End of 3D Interface pass right
if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled))
{
// Render 2D GUI in 3D space, assume existing camera is OK
renderGUI();
// Recycle render target
m_Driver->getRenderTargetManager().recycleRenderTarget(m_GUITexture);
m_GUITexture = NULL;
}
// End 3D scene render target
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);
nlassert(m_SceneTexture);
CTextureUser texNull;
(static_cast<CDriverUser *>(m_Driver))->setRenderTarget(texNull);
bool fogEnabled = m_Driver->fogEnabled();
m_Driver->enableFog(false);
@ -632,7 +836,7 @@ bool CStereoOVR::endRenderTarget()
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);
barrelMat->setTexture(0, m_SceneTexture->getITexture());
drvInternal->activePixelProgram(m_PixelProgram);
@ -697,8 +901,13 @@ bool CStereoOVR::endRenderTarget()
drvInternal->activePixelProgram(NULL);
m_Driver->enableFog(fogEnabled);
// Recycle render target
m_Driver->getRenderTargetManager().recycleRenderTarget(m_SceneTexture);
m_SceneTexture = NULL;
return true;
}
return false;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,4 @@
// TODO
/* end of file */

View file

@ -21,6 +21,8 @@ limitations under the License.
************************************************************************************/
#include "std3d.h"
namespace NL3D {
const char *g_StereoOVR_fp40 =
"!!ARBfp1.0\n"

View file

@ -1,354 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdmisc.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/events.h"
#include "nel/misc/win_event_emitter.h"
//
#include "di_mouse_device.h"
#include "di_keyboard_device.h"
#include "di_game_device.h"
#ifdef NL_OS_WINDOWS
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
namespace NLMISC
{
static const char DirectInputLibName[] = "dinput8.dll";
/////////////////////////////////
// CDIEventEmitter statics //
/////////////////////////////////
HMODULE CDIEventEmitter::_DirectInputLibHandle = 0;
CDIEventEmitter::TPDirectInput8Create CDIEventEmitter::_PDirectInput8Create = NULL;
uint CDIEventEmitter::_NumCreatedInterfaces = 0;
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////
// CDIEventEmitter implementation //
////////////////////////////////////
//======================================================
CDIEventEmitter::CDIEventEmitter(HWND hwnd, CWinEventEmitter *we)
:
_hWnd(hwnd),
_WE(we),
_DInput8(NULL),
_Keyboard(NULL),
_Mouse(NULL),
_ButtonsFlags(noButton)
{
}
//======================================================
CDIEventEmitter::~CDIEventEmitter()
{
releaseMouse();
releaseKeyboard();
// release all devices
while (_DeviceServer.getNumDevices() != 0)
{
IInputDevice *dev = _DeviceServer.getDevice(0);
_DeviceServer.removeDevice(dev);
delete dev;
}
if (_DInput8) _DInput8->Release();
-- _NumCreatedInterfaces;
if (_NumCreatedInterfaces == 0) unloadLib();
}
//======================================================
CDIEventEmitter *CDIEventEmitter::create(HINSTANCE hinst, HWND hwnd, CWinEventEmitter *we) throw(EDirectInput)
{
if (!loadLib()) throw EDirectInputLibNotFound();
std::auto_ptr<CDIEventEmitter> dxee(new CDIEventEmitter(hwnd, we));
HRESULT result = _PDirectInput8Create(hinst,
DIRECTINPUT_VERSION,
IID_IDirectInput8A,
(void **) &dxee->_DInput8,
NULL);
if (result != DI_OK) throw EDirectInputInitFailed();
// ok, everything's fine, commit changes
++_NumCreatedInterfaces;
return dxee.release();
}
//======================================================
bool CDIEventEmitter::loadLib()
{
if (_DirectInputLibHandle != 0) return true; // library already loaded ?
HMODULE handle = ::LoadLibrary(DirectInputLibName);
if (handle == 0) return false;
// try to get the creation function
TPDirectInput8Create cf = (TPDirectInput8Create) ::GetProcAddress(handle, "DirectInput8Create");
if (!cf)
{
::FreeLibrary(handle);
return false;
}
// commit changes
_DirectInputLibHandle = handle;
_PDirectInput8Create = cf;
return true;
}
//======================================================
void CDIEventEmitter::unloadLib()
{
nlassert(_DirectInputLibHandle != 0);
::FreeLibrary(_DirectInputLibHandle);
_DirectInputLibHandle = 0;
_PDirectInput8Create = NULL;
}
//======================================================
void CDIEventEmitter::poll(CEventServer *server)
{
if (_WE) _ButtonsFlags = _WE->buildFlags();
if (!server)
server=&_InternalServer;
_DeviceServer.poll(server);
}
//======================================================
TMouseButton CDIEventEmitter::buildButtonsFlags() const
{
uint mouseFlags;
uint keybFlags;
//
if (_Mouse) // takes the flags from the direct input mouse
{
mouseFlags = (_Mouse->getButton(0) ? leftButton : 0)
| (_Mouse->getButton(1) ? rightButton : 0)
| (_Mouse->getButton(2) ? middleButton : 0);
}
else // takes the flags from the system mouse
{
mouseFlags = _ButtonsFlags & (leftButton | rightButton | middleButton);
}
//
if (_Keyboard) // takes the flags from the direct input keyboard
{
keybFlags = (_Keyboard->ShiftPressed ? shiftButton : 0)
| (_Keyboard->AltPressed ? altButton : 0)
| (_Keyboard->CtrlPressed ? ctrlButton : 0);
}
else // takes the flags from the system keyboard
{
keybFlags = _ButtonsFlags & (shiftButton | altButton | ctrlButton);
}
return (TMouseButton) (keybFlags | mouseFlags);
}
//======================================================
IMouseDevice *CDIEventEmitter::getMouseDevice(bool hardware) throw(EInputDevice)
{
if (_Mouse) return _Mouse; // already created ?
try
{
// Create a mouse
std::auto_ptr<CDIMouse> mouse(CDIMouse::createMouseDevice(_DInput8, _hWnd, this, hardware, _WE));
// register to the device server
_DeviceServer.registerDevice(mouse.get());
_Mouse = mouse.get();
return mouse.release();
}
catch (...)
{
if (_WE) _WE->enableMouseEvents(true);
throw;
}
}
//======================================================
void CDIEventEmitter::releaseMouse()
{
if (!_Mouse) return;
// reupdate the system keyboard flags
if (_WE)
{
_WE->resetButtonFlagState();
_WE->enableMouseEvents(true);
}
// remove the device
_DeviceServer.removeDevice(_Mouse);
delete _Mouse;
_Mouse = NULL;
}
//===========================================================================
IKeyboardDevice *CDIEventEmitter::getKeyboardDevice() throw(EInputDevice)
{
if (_Keyboard) return _Keyboard;
try
{
// create a keyboard
std::auto_ptr<CDIKeyboard> keyboard(CDIKeyboard::createKeyboardDevice(_DInput8, _hWnd, this, _WE));
// register to the device server
_DeviceServer.registerDevice(keyboard.get());
_Keyboard = keyboard.get();
return keyboard.release();
}
catch (...)
{
if (_WE) _WE->enableKeyboardEvents(true);
throw;
}
}
//==========================================================================
void CDIEventEmitter::releaseKeyboard()
{
if (!_Keyboard) return;
// reupdate the system keyboard flags
if (_WE)
{
_WE->resetButtonFlagState();
_WE->enableKeyboardEvents(true);
}
//
_DeviceServer.removeDevice(_Keyboard);
delete _Keyboard;
_Keyboard = NULL;
}
//==========================================================================
void CDIEventEmitter::submitEvents(CEventServer &server, bool allWindows)
{
_InternalServer.setServer(&server);
_InternalServer.pump(allWindows);
}
//==========================================================================
void CDIEventEmitter::emulateMouseRawMode(bool enable)
{
nlerror("no raw mode emulation on windows, the CDIMouse has a real raw mode");
}
//==========================================================================
/// Tool fct to retrieve the game devices.
static BOOL CALLBACK DIEnumDevicesDescCallback
(
LPCDIDEVICEINSTANCE lpddi,
LPVOID pvRef
)
{
CGameDeviceDesc desc;
desc.InstanceName = lpddi->tszInstanceName;
desc.ProductName = lpddi->tszProductName;
switch (lpddi->wUsage & 0xff)
{
case DI8DEVTYPE_JOYSTICK: desc.DevType = CGameDeviceDesc::Joystick; break;
case DI8DEVTYPE_GAMEPAD: desc.DevType = CGameDeviceDesc::GamePad; break;
default: desc.DevType = CGameDeviceDesc::DontKnow; break;
}
TDeviceDescVect *dv = (TDeviceDescVect *) pvRef;
dv->push_back(desc);
return DIENUM_CONTINUE;
}
//==========================================================================
/// Tool fct to retrieve the game devices GUID
static BOOL CALLBACK DIEnumDevicesGUIDCallback
(
LPCDIDEVICEINSTANCE lpddi,
LPVOID pvRef
)
{
std::vector<GUID> *gv = (std::vector<GUID> *) pvRef;
gv->push_back(lpddi->guidInstance);
return DIENUM_CONTINUE;
}
//==========================================================================
void CDIEventEmitter::enumerateGameDevice(TDeviceDescVect &descs) throw(EInputDevice)
{
uint k;
nlassert(_DInput8);
descs.clear();
// enum all devices of interest
_DInput8->EnumDevices(DI8DEVCLASS_GAMECTRL, &DIEnumDevicesDescCallback, (LPVOID) &descs, DIEDFL_ALLDEVICES);
for (k = 0; k < descs.size(); ++k) descs[k].Connected = false;
// enum all connected devices
static TDeviceDescVect connecteds;
_DInput8->EnumDevices(DI8DEVCLASS_GAMECTRL, &DIEnumDevicesDescCallback, (LPVOID) &connecteds, DIEDFL_ATTACHEDONLY);
// see which devices are connected
for (k = 0; k < connecteds.size(); ++k)
{
TDeviceDescVect::iterator it = std::find(descs.begin(), descs.end(), connecteds[k]);
it->Connected = true;
}
}
//==========================================================================
IGameDevice *CDIEventEmitter::createGameDevice(const std::string &instanceName) throw(EInputDevice)
{
static TDeviceDescVect deviceDescs;
static std::vector<GUID> deviceGUID;
nlassert(_DInput8);
enumerateGameDevice(deviceDescs);
// get the ID for each device
deviceGUID.clear();
HRESULT r = _DInput8->EnumDevices(DI8DEVCLASS_GAMECTRL, &DIEnumDevicesGUIDCallback, (LPVOID) &deviceGUID, DIEDFL_ALLDEVICES);
nlassert(r == DI_OK);
nlassert(deviceDescs.size() == deviceGUID.size());
// search the device that match the instance name
for (uint k = 0; k < deviceDescs.size(); ++k)
{
if (deviceDescs[k].InstanceName == instanceName)
{
std::auto_ptr<CDIGameDevice> gd(CDIGameDevice::createGameDevice(_DInput8, _hWnd, this, deviceDescs[k], deviceGUID[k]));
// insert in the device server
_DeviceServer.registerDevice(gd.get());
return gd.release();
}
}
return NULL;
}
//==========================================================================
void CDIEventEmitter::releaseGameDevice(IGameDevice *gd)
{
nlassert(gd);
CDIGameDevice *digd = safe_cast<CDIGameDevice *>(gd);
_DeviceServer.removeDevice(digd);
delete gd;
}
} // NLMISC
#endif // NL_OS_WINDOWS

View file

@ -1,523 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdmisc.h"
#include "di_game_device.h"
#include "nel/misc/game_device_events.h"
#ifdef NL_OS_WINDOWS
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
namespace NLMISC
{
//============================================================================
CDIGameDevice::CDIGameDevice() : _Device(NULL)
{
::memset(&_CurrentState, 0, sizeof(_CurrentState));
}
//============================================================================
CDIGameDevice::~CDIGameDevice()
{
if (_Device)
{
_Device->Unacquire();
_Device->Release();
}
}
//============================================================================
CDIGameDevice *CDIGameDevice::createGameDevice(IDirectInput8 *di8,
HWND hwnd,
CDIEventEmitter *diEventEmitter,
const CGameDeviceDesc &desc,
REFGUID rguid) throw(EDirectInput)
{
nlassert(diEventEmitter);
nlassert(di8);
std::auto_ptr<CDIGameDevice> dev(new CDIGameDevice);
//
HRESULT r = di8->CreateDevice(rguid, &dev->_Device, NULL);
if (r != DI_OK) throw EDirectInputGameDeviceNotCreated();
r = dev->_Device->SetDataFormat(pJoyDataFormat);
nlassert(r == DI_OK);
//
r = dev->_Device->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
if (r != DI_OK) throw EDirectInputCooperativeLevelFailed();
//
//
dev->_Desc = desc;
dev->_EventEmitter = diEventEmitter;
dev->querryControls();
return dev.release();
}
//============================================================================
void CDIGameDevice::begin(CEventServer *server)
{
nlassert(_Device);
HRESULT r;
r = _Device->Poll();
if (r == DIERR_INPUTLOST || r == DIERR_NOTACQUIRED)
{
r = _Device->Acquire();
if (r != DI_OK) return;
r = _Device->Poll();
if (r != DI_OK) return;
}
CDIJoyState newState;
r = _Device->GetDeviceState(sizeof(CDIJoyState), &newState);
if (r != DI_OK) return;
uint k;
//////////
// Axis //
//////////
for (k = 0; k < MaxNumAxis; ++k)
{
CAxis &axis = _Axis[k];
if (axis.Present)
{
if (((LONG *) &newState)[k] != ((LONG *) &_CurrentState)[k]) // state changed ?
{
// update position
axis.Value = 2.f * (((LONG *) &newState)[k] - axis.Min) / (float) (axis.Max - axis.Min) - 1.f;
// create event
CGDAxisMoved *event = new CGDAxisMoved((IGameDevice::TAxis) k, axis.Value, this, _EventEmitter);
// update state
((LONG *) &_CurrentState)[k] = ((LONG *) &newState)[k];
//
server->postEvent(event);
//
}
}
}
/////////////
// Buttons //
/////////////
for (k = 0; k < _Buttons.size(); ++k)
{
CButton &bt = _Buttons[k];
if ((newState.rgbButtons[k] & 0x80) != (_CurrentState.rgbButtons[k] & 0x80))
{
bool pushed = (newState.rgbButtons[k] & 0x80) != 0;
// update the state of the button
bt.Pushed = pushed;
CGDButton *event;
if (pushed) event = new CGDButtonDown(k, this, _EventEmitter);
else event = new CGDButtonUp(k, this, _EventEmitter);
// update state
_CurrentState.rgbButtons[k] = newState.rgbButtons[k];
server->postEvent(event);
}
}
/////////////
// Sliders //
/////////////
for (k = 0; k < _Sliders.size(); ++k)
{
CSlider &sl = _Sliders[k];
if (newState.rglSlider[k] != _CurrentState.rglSlider[k]) // state changed ?
{
// update position
sl.Pos = ( newState.rglSlider[k] - sl.Min) / (float) (sl.Max - sl.Min);
// create event
CGDSliderMoved *event = new CGDSliderMoved(sl.Pos, k, this, _EventEmitter);
// update state
_CurrentState.rglSlider[k] = newState.rglSlider[k];
//
server->postEvent(event);
}
}
//////////
// POVs //
//////////
for (k = 0; k < _POVs.size(); ++k)
{
CPOV &pov = _POVs[k];
if (newState.rgdwPOV[k] != _CurrentState.rgdwPOV[k]) // state changed ?
{
DWORD value = newState.rgdwPOV[k];
pov.Centered = (LOWORD(value) == 0xFFFF);
if (!pov.Centered)
{
// update position
pov.Angle = value / 100.f;
}
// create event
CGDPOVChanged *event = new CGDPOVChanged(pov.Centered, pov.Angle, k, this, _EventEmitter);
// update state
_CurrentState.rgdwPOV[k] = newState.rgdwPOV[k];
//
server->postEvent(event);
}
}
}
//============================================================================
void CDIGameDevice::poll(CInputDeviceServer *dev)
{
// buffered datas not supported
}
//============================================================================
void CDIGameDevice::submit(IInputDeviceEvent *deviceEvent, CEventServer *server)
{
// should never be called, buffered datas not supported
nlassert(0);
}
//============================================================================
/** Tool fct : tests whether a DIDEVICEOBJECTINSTANCE contains a controls name and return it,
* or build a default one
*/
static void BuildCtrlName(LPCDIDEVICEOBJECTINSTANCE lpddoi,
std::string &destName,
const char *defaultName)
{
if (lpddoi->dwSize >= offsetof(DIDEVICEOBJECTINSTANCE, tszName) + sizeof(TCHAR[MAX_PATH]))
{
destName = (::strcmp("N/A", lpddoi->tszName) == 0) ? defaultName
: lpddoi->tszName;
}
else
{
destName = defaultName;
}
}
//============================================================================
// A callback to enumerate the controls of a device
BOOL CALLBACK DIEnumDeviceObjectsCallback
(
LPCDIDEVICEOBJECTINSTANCE lpddoi,
LPVOID pvRef
)
{
CDIGameDevice *gd = (CDIGameDevice *) pvRef;
return gd->processEnumObject(lpddoi);
}
//=======================================================================
// get range for an axis
static HRESULT GetDIAxisRange(LPDIRECTINPUTDEVICE8 device, uint offset, DWORD type, sint &min, sint &max)
{
DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof(DIPROPRANGE);
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
diprg.diph.dwHow = DIPH_BYOFFSET;
diprg.diph.dwObj = offset;
// Set the range for the axis
HRESULT r = device->GetProperty(DIPROP_RANGE, &diprg.diph);
if (r == DIERR_OBJECTNOTFOUND)
{
// try from its ID
diprg.diph.dwHow = DIPH_BYID;
diprg.diph.dwObj = type;
// Set the range for the axis
HRESULT r = device->GetProperty(DIPROP_RANGE, &diprg.diph);
if (r != DI_OK)
{
// setup default values ...
min = 0;
max = 65535;
return r;
}
}
else if (r != DI_OK)
{
min = 0;
max = 65535;
return r;
}
/* switch (r)
{
default:
nlinfo("ok");
break;
case DIERR_INVALIDPARAM:
nlinfo("invalid param");
break;
case DIERR_NOTEXCLUSIVEACQUIRED:
nlinfo("DIERR_NOTEXCLUSIVEACQUIRED");
break;
case DIERR_NOTINITIALIZED:
nlinfo("DIERR_NOTINITIALIZED");
break;
case DIERR_OBJECTNOTFOUND:
nlinfo("DIERR_OBJECTNOTFOUND");
break;
case DIERR_UNSUPPORTED:
nlinfo("DIERR_UNSUPPORTED");
break;
}*/
min = (sint) diprg.lMin;
max = (sint) diprg.lMax;
return r;
}
//============================================================================
BOOL CDIGameDevice::processEnumObject(LPCDIDEVICEOBJECTINSTANCE lpddoi)
{
// the dwSize field gives us the size of the objects, and the available fields
// has this object the field guidType and dwOfs ?
if (lpddoi->dwSize < offsetof(DIDEVICEOBJECTINSTANCE, dwOfs) + sizeof(DWORD)) return DIENUM_CONTINUE;
uint ctrlType = (uint) lpddoi->dwType;
///////////////////////////////////////////
// axis, we only support absolute ones //
///////////////////////////////////////////
if (lpddoi->guidType == GUID_XAxis && (ctrlType & DIDFT_ABSAXIS) )
{
GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[XAxis].Min, _Axis[XAxis].Max);
BuildCtrlName(lpddoi, _Axis[XAxis].Name, "X Axis");
_Axis[XAxis].Present = true;
return DIENUM_CONTINUE;
}
if (lpddoi->guidType == GUID_YAxis && (ctrlType & DIDFT_ABSAXIS))
{
GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[YAxis].Min, _Axis[YAxis].Max);
BuildCtrlName(lpddoi, _Axis[YAxis].Name, "Y Axis");
_Axis[YAxis].Present = true;
return DIENUM_CONTINUE;
}
if (lpddoi->guidType == GUID_ZAxis && (ctrlType & DIDFT_ABSAXIS))
{
GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[ZAxis].Min, _Axis[ZAxis].Max);
BuildCtrlName(lpddoi, _Axis[ZAxis].Name, "Z Axis");
_Axis[ZAxis].Present = true;
return DIENUM_CONTINUE;
}
if (lpddoi->guidType == GUID_RxAxis && (ctrlType & DIDFT_ABSAXIS))
{
GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[RXAxis].Min, _Axis[RXAxis].Max);
BuildCtrlName(lpddoi, _Axis[RXAxis].Name, "RX Axis");
_Axis[RXAxis].Present = true;
return DIENUM_CONTINUE;
}
if (lpddoi->guidType == GUID_RyAxis && (ctrlType & DIDFT_ABSAXIS))
{
GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[RYAxis].Min, _Axis[RYAxis].Max);
BuildCtrlName(lpddoi, _Axis[RYAxis].Name, "RY Axis");
_Axis[RYAxis].Present = true;
return DIENUM_CONTINUE;
}
if (lpddoi->guidType == GUID_RzAxis && (ctrlType & DIDFT_ABSAXIS))
{
GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Axis[RZAxis].Min, _Axis[RZAxis].Max);
BuildCtrlName(lpddoi, _Axis[RZAxis].Name, "RZ Axis");
_Axis[RZAxis].Present = true;
return DIENUM_CONTINUE;
}
// has this object the field dwType ?
if (lpddoi->dwSize < offsetof(DIDEVICEOBJECTINSTANCE, dwType) + sizeof(DWORD)) return DIENUM_CONTINUE;
uint type = lpddoi->dwType;
/////////////
// Buttons //
/////////////
if (type & DIDFT_BUTTON)
{
if (_Buttons.size() < MaxNumButtons)
{
_Buttons.push_back(CButton());
uint buttonIndex = (uint)_Buttons.size() - 1;
char defaultButtonName[32];
smprintf(defaultButtonName, 32, "BUTTON %d", buttonIndex + 1);
BuildCtrlName(lpddoi, _Buttons[buttonIndex].Name, defaultButtonName);
return DIENUM_CONTINUE;
}
}
/////////////
// Sliders //
/////////////
if (type & DIDFT_ABSAXIS)
{
if (_Sliders.size() < MaxNumSliders)
{
_Sliders.push_back(CSlider());
uint sliderIndex = (uint)_Sliders.size() - 1;
GetDIAxisRange(_Device, lpddoi->dwOfs, lpddoi->dwType, _Sliders[sliderIndex].Min, _Sliders[sliderIndex].Max);
char defaultSliderName[32];
smprintf(defaultSliderName, 32, "SLIDER %d", sliderIndex + 1);
BuildCtrlName(lpddoi, _Sliders[sliderIndex].Name, defaultSliderName);
}
return DIENUM_CONTINUE;
}
//////////
// POVs //
//////////
if (type & DIDFT_POV)
{
if (_POVs.size() < MaxNumPOVs)
{
_POVs.push_back(CPOV());
uint povIndex = (uint)_POVs.size() - 1;
char defaultPOVName[16];
smprintf(defaultPOVName, 16, "POV %d", povIndex + 1);
BuildCtrlName(lpddoi, _POVs[povIndex].Name, defaultPOVName);
}
return DIENUM_CONTINUE;
}
return DIENUM_CONTINUE;
}
//============================================================================
void CDIGameDevice::querryControls()
{
HRESULT r = _Device->EnumObjects(&DIEnumDeviceObjectsCallback, (LPVOID) this, DIDFT_ALL);
nlassert(r == DI_OK);
}
//============================================================================
bool CDIGameDevice::setBufferSize(uint size)
{
// uisually not supported by this kind of devices
return false;
}
//============================================================================
uint CDIGameDevice::getBufferSize() const
{
// uisually not supported by this kind of devices
return 0;
}
//============================================================================
uint CDIGameDevice::getNumButtons() const
{
return (uint)_Buttons.size();
}
//============================================================================
bool CDIGameDevice::hasAxis(TAxis axis) const
{
nlassert(axis < MaxNumAxis);
return _Axis[axis].Present;
}
//============================================================================
uint CDIGameDevice::getNumSliders() const
{
return (uint)_Sliders.size();
}
//============================================================================
uint CDIGameDevice::getNumPOV() const
{
return (uint)_POVs.size();
}
//============================================================================
const char *CDIGameDevice::getButtonName(uint index) const
{
nlassert(index < _Buttons.size());
return _Buttons[index].Name.c_str();
}
//============================================================================
const char *CDIGameDevice::getAxisName(TAxis axis) const
{
nlassert(axis < MaxNumAxis);
nlassert(hasAxis(axis)); // ! Not an axis of this device
return _Axis[axis].Name.c_str();
}
//============================================================================
const char *CDIGameDevice::getSliderName(uint index) const
{
nlassert(index < _Sliders.size());
return _Sliders[index].Name.c_str();
}
//============================================================================
const char *CDIGameDevice::getPOVName(uint index) const
{
nlassert(index < _POVs.size());
return _POVs[index].Name.c_str();
}
//============================================================================
bool CDIGameDevice::getButtonState(uint index) const
{
nlassert(index < _Buttons.size());
return _Buttons[index].Pushed;
}
//============================================================================
float CDIGameDevice::getAxisValue(TAxis axis) const
{
nlassert(axis < MaxNumAxis);
nlassert(hasAxis(axis)); // ! Not an axis of this device
return _Axis[axis].Value;
}
//============================================================================
float CDIGameDevice::getSliderPos(uint index) const
{
nlassert(index < _Sliders.size());
return _Sliders[index].Pos;
}
//============================================================================
float CDIGameDevice::getPOVAngle(uint index) const
{
nlassert(index < _POVs.size());
return _POVs[index].Angle;
}
} // NLMISC
#endif // NL_OS_WINDOWS

View file

@ -1,170 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_DI_GAME_DEVICE_H
#define NL_DI_GAME_DEVICE_H
#include "nel/misc/types_nl.h"
#ifdef NL_OS_WINDOWS
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/game_device.h"
namespace NLMISC
{
//
typedef DIJOYSTATE2 CDIJoyState;
const DIDATAFORMAT * const pJoyDataFormat = &c_dfDIJoystick2;
const uint MaxNumSliders = 2;
const uint MaxNumPOVs = 4;
const uint MaxNumButtons = 128;
//
struct EDirectInputGameDeviceNotCreated : EDirectInput
{
EDirectInputGameDeviceNotCreated() : EDirectInput("Unable to create a game device") {}
};
/**
* Direct input implementation of a game device.
*/
class CDIGameDevice : public IGameDevice
{
public:
/// Create a direct input game device from the given RGUID. Destroy it with delete
static CDIGameDevice *createGameDevice(IDirectInput8 *di8,
HWND hwnd,
CDIEventEmitter *diEventEmitter,
const CGameDeviceDesc &desc,
REFGUID rguid) throw(EDirectInput);
~CDIGameDevice();
///\name From IInputDevice
//@{
virtual bool setBufferSize(uint size);
virtual uint getBufferSize() const;
//@}
///\name From IGameDevice
//@{
virtual const CGameDeviceDesc &getDescription() const { return _Desc; }
//
virtual uint getNumButtons() const;
virtual bool hasAxis(TAxis axis) const;
virtual uint getNumSliders() const;
virtual uint getNumPOV() const;
//
virtual const char *getButtonName(uint index) const;
virtual const char *getAxisName(TAxis axis) const;
virtual const char *getSliderName(uint index) const;
virtual const char *getPOVName(uint index) const;
//
virtual bool getButtonState(uint index) const;
virtual float getAxisValue(TAxis axis) const;
virtual float getSliderPos(uint index) const;
virtual float getPOVAngle(uint index) const;
//@}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
private:
// base class for controls
struct CCtrl
{
std::string Name;
};
// a button
struct CButton : public CCtrl
{
bool Pushed;
CButton() : Pushed(false) {}
};
// an axis. Its value either gives its position (-1 .. 1) or its angle (CCW in radians)
struct CAxis : public CCtrl
{
bool Present; // is this axis used ?
// min and max values from Direct Input
sint Min, Max;
float Value;
CAxis() : Value(0.f), Present(false) {}
};
// a slider
struct CSlider : public CCtrl
{
sint Min, Max;
float Pos;
CSlider() : Pos(0.f) {}
};
// a POV
struct CPOV : public CCtrl
{
bool Centered;
float Angle;
CPOV() : Angle(0.f), Centered(true) {}
};
private:
// ctor
CDIGameDevice();
///\name From IInputDevice
//@{
virtual void begin(CEventServer *server);
virtual void poll(CInputDeviceServer *dev);
virtual void submit(IInputDeviceEvent *deviceEvent, CEventServer *server);
//@}
/** Get the controls (buttons, slider..) of this device from the Direct Input interface to build this object infos.
*/
void querryControls();
/// Called during EnumObject
BOOL processEnumObject(LPCDIDEVICEOBJECTINSTANCE lpddoi);
friend BOOL CALLBACK DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef);
private:
LPDIRECTINPUTDEVICE8 _Device;
CGameDeviceDesc _Desc;
CDIEventEmitter *_EventEmitter;
///\name Device infos
//@{
CAxis _Axis[MaxNumAxis];
std::vector<CButton> _Buttons;
std::vector<CSlider> _Sliders;
std::vector<CPOV> _POVs;
//@}
CDIJoyState _CurrentState;
};
} // NLMISC
#endif // NL_OS_WINDOWS
#endif // NL_DI_GAME_DEVICE_H
/* End of di_play_device.h */

View file

@ -1,686 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdmisc.h"
#include "di_keyboard_device.h"
#ifdef NL_OS_WINDOWS
#include "nel/misc/win_event_emitter.h"
#include <dinput.h>
#include <Winuser.h>
#include "Mmsystem.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
namespace NLMISC
{
// used to do a conversion from DX key code to Nel keys enums
struct CKeyConv
{
uint DIKey;
TKey NelKey;
const char *KeyName;
bool Repeatable;
};
// this is used to build a conversion table
static const CKeyConv DIToNel[] =
{
//
{DIK_F1, KeyF1, "F1", true},
{DIK_F2, KeyF2, "F2", true},
{DIK_F3, KeyF3, "F3", true},
{DIK_F4, KeyF4, "F4", true},
{DIK_F5, KeyF5, "F5", true},
{DIK_F6, KeyF6, "F6", true},
{DIK_F7, KeyF7, "F7", true},
{DIK_F8, KeyF8, "F8", true},
{DIK_F9, KeyF9, "F9", true},
{DIK_F10, KeyF10, "F10", true},
{DIK_F11, KeyF11, "F11", true},
{DIK_F12, KeyF12, "F12", true},
{DIK_F13, KeyF13, "F13", true},
{DIK_F14, KeyF14, "F14", true},
{DIK_F15, KeyF15, "F15", true},
//
{DIK_NUMPAD0, KeyNUMPAD0, "NUMPAD0", true},
{DIK_NUMPAD1, KeyNUMPAD1, "NUMPAD1", true},
{DIK_NUMPAD2, KeyNUMPAD2, "NUMPAD2", true},
{DIK_NUMPAD3, KeyNUMPAD3, "NUMPAD3", true},
{DIK_NUMPAD4, KeyNUMPAD4, "NUMPAD4", true},
{DIK_NUMPAD5, KeyNUMPAD5, "NUMPAD5", true},
{DIK_NUMPAD6, KeyNUMPAD6, "NUMPAD6", true},
{DIK_NUMPAD7, KeyNUMPAD7, "NUMPAD7", true},
{DIK_NUMPAD8, KeyNUMPAD8, "NUMPAD8", true},
{DIK_NUMPAD9, KeyNUMPAD9, "NUMPAD9", true},
//
{DIK_DIVIDE, KeyDIVIDE, "/", true},
{DIK_DECIMAL, KeyDECIMAL, "NUMPAD .", true},
//
{DIK_LSHIFT, KeyLSHIFT, "LEFT SHIFT", false},
{DIK_RSHIFT, KeyRSHIFT, "RIGHT SHIFT", false},
//
{DIK_LCONTROL, KeyLCONTROL, "LEFT CONTROL", false},
{DIK_RCONTROL, KeyRCONTROL, "RIGHT CONTROL", false},
//
{DIK_LMENU, KeyLMENU, "ALT", false},
{DIK_RMENU, KeyRMENU, "ALT GR", false},
//
{DIK_UP, KeyUP, "UP", true},
{DIK_PRIOR, KeyPRIOR, "PRIOR", true},
{DIK_LEFT, KeyLEFT, "LEFT", true},
{DIK_RIGHT, KeyRIGHT, "RIGHT", true},
{DIK_END, KeyEND, "END", true},
{DIK_DOWN, KeyDOWN, "DOWN", true},
{DIK_NEXT, KeyNEXT, "NEXT", true},
{DIK_INSERT, KeyINSERT, "INSERT", true},
{DIK_DELETE, KeyDELETE, "DELETE", true},
{DIK_HOME, KeyHOME, "HOME", true},
{DIK_LWIN, KeyLWIN, "LEFT WIN", false},
{DIK_RWIN, KeyRWIN, "RIGHT WIN", false},
{DIK_APPS, KeyAPPS, "APPS", false},
{DIK_BACK, KeyBACK, "BACK", true},
//
{DIK_SYSRQ, KeySNAPSHOT, "SNAPSHOT", false},
{DIK_SCROLL, KeySCROLL, "SCROLL", false},
{DIK_PAUSE, KeyPAUSE, "PAUSE", false},
//
{DIK_NUMLOCK, KeyNUMLOCK, "NUMLOCK", false},
//
{DIK_NUMPADENTER, KeyRETURN, "RETURN", true},
//{DIK_NUMPADENTER, KeyRETURN, "ENTER", true},
//
{DIK_CONVERT, KeyCONVERT, "CONVERT", false},
{DIK_NOCONVERT, KeyNONCONVERT, "NOCONVERT", true},
//
{DIK_KANA, KeyKANA, "KANA", false},
{DIK_KANJI, KeyKANJI, "KANJI", false},
};
///========================================================================
const CKeyConv *CDIKeyboard::DIKeyToNelKeyTab[CDIKeyboard::NumKeys];
///========================================================================
CDIKeyboard::CDIKeyboard(CWinEventEmitter *we, HWND hwnd)
: _Keyboard(NULL),
_WE(we),
ShiftPressed(false),
CtrlPressed(false),
AltPressed(false),
_CapsLockToggle(true),
_hWnd(hwnd),
_RepeatDelay(250),
_RepeatPeriod(200),
_FirstPressDate(-1),
_LastDIKeyPressed(0)
{
if (::GetKeyboardState((PBYTE) _VKKeyState) == FALSE)
{
std::fill(_VKKeyState, _VKKeyState + NumKeys, 0);
}
// test whether the user toggle its keyboard with shift or not..
HKEY hKey;
if (::RegOpenKeyEx(HKEY_CURRENT_USER, "Keyboard Layout", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
DWORD type = REG_DWORD;
DWORD value;
DWORD size = sizeof(DWORD);
if (::RegQueryValueEx(hKey, "Attributes", NULL, &type, (LPBYTE) &value, &size) == ERROR_SUCCESS)
{
_CapsLockToggle = (value & (1 << 16)) == 0;
}
::RegCloseKey(hKey);
}
// get repeat delay and period
int keybDelay;
if (::SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &keybDelay, 0) != 0)
{
_RepeatDelay = 250 + 250 * keybDelay;
}
DWORD keybSpeed;
if (::SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &keybSpeed, 0) != 0)
{
_RepeatPeriod = (uint) (1000.f / (keybSpeed * (27.5f / 31.f) + 2.5f));
}
// get keyboard layout
_KBLayout = ::GetKeyboardLayout(0);
_RepetitionDisabled.resize(NumKeys);
_RepetitionDisabled.clearAll();
}
///========================================================================
void CDIKeyboard::updateVKKeyState(uint diKey, bool pressed, TKey &keyValue, TKey &charValue)
{
bool extKey;
bool repeatable;
keyValue = DIKeyToNelKey(diKey, extKey, repeatable);
//
if (keyValue == 0)
{
charValue = keyValue;
return;
}
//
if (pressed)
{
// check for toggle key
switch (keyValue)
{
case KeyPAUSE:
case KeyKANA:
case KeyKANJI:
_VKKeyState[keyValue] ^= 0x01; // toggle first bit
break;
case KeyCAPITAL:
if (_CapsLockToggle)
{
_VKKeyState[keyValue] ^= 0x01;
//toggleCapsLock(false);
}
else
{
if ((_VKKeyState[keyValue] & 0x01) == 0)
{
_VKKeyState[keyValue] |= 0x01;
//toggleCapsLock(false);
}
}
break;
case KeyNUMLOCK:
_VKKeyState[keyValue] ^= 0x01;
//setNumLock((_VKKeyState[keyValue] & 0x01) != 0);
break;
case KeySCROLL:
_VKKeyState[keyValue] ^= 0x01;
//toggleScrollLock();
break;
}
_VKKeyState[keyValue] |= 0x80;
}
else
{
_VKKeyState[keyValue] &= ~0x80;
}
//
switch (keyValue)
{
case KeyLSHIFT: charValue = KeySHIFT; break;
case KeyRSHIFT: charValue = KeySHIFT; break;
case KeyLCONTROL: charValue = KeyCONTROL; break;
case KeyRCONTROL: charValue = KeyCONTROL; break;
case KeyLMENU: charValue = KeyMENU; break;
case KeyRMENU: charValue = KeyMENU; break;
default: charValue = keyValue; break;
}
//
if (charValue == KeySHIFT && !_CapsLockToggle)
{
if (_VKKeyState[KeyCAPITAL] & 0x01)
{
_VKKeyState[KeyCAPITAL] &= ~0x01;
//toggleCapsLock(true);
}
}
//
if (charValue != keyValue)
{
_VKKeyState[charValue] = _VKKeyState[keyValue];
}
//
updateCtrlAltShiftValues();
}
///========================================================================
void CDIKeyboard::updateCtrlAltShiftValues()
{
ShiftPressed = (_VKKeyState[KeySHIFT] & 0x80) != 0;
CtrlPressed = (_VKKeyState[KeyCONTROL] & 0x80) != 0;
AltPressed = (_VKKeyState[KeyMENU] & 0x80) != 0;
}
///========================================================================
CDIKeyboard::~CDIKeyboard()
{
if (_Keyboard)
{
_Keyboard->Unacquire();
_Keyboard->Release();
}
}
///========================================================================
CDIKeyboard *CDIKeyboard::createKeyboardDevice(IDirectInput8 *di8,
HWND hwnd,
CDIEventEmitter *diEventEmitter,
CWinEventEmitter *we
) throw(EDirectInput)
{
std::auto_ptr<CDIKeyboard> kb(new CDIKeyboard(we, hwnd));
kb->_DIEventEmitter = diEventEmitter;
HRESULT result = di8->CreateDevice(GUID_SysKeyboard, &kb->_Keyboard, NULL);
if (result != DI_OK) throw EDirectInputNoKeyboard();
result = kb->_Keyboard->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
if (result != DI_OK) throw EDirectInputCooperativeLevelFailed();
result = kb->_Keyboard->SetDataFormat(&c_dfDIKeyboard);
kb->setBufferSize(16);
kb->_Keyboard->Acquire();
// Enable win32 keyboard messages only if hardware mouse in normal mode
if (kb->_WE)
kb->_WE->enableKeyboardEvents(false);
return kb.release();
}
///========================================================================
void CDIKeyboard::poll(CInputDeviceServer *dev)
{
nlassert(_Keyboard);
nlassert(_KeyboardBufferSize > 0);
static std::vector<DIDEVICEOBJECTDATA> datas;
datas.resize(_KeyboardBufferSize);
DWORD numElements = _KeyboardBufferSize;
HRESULT result = _Keyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &datas[0], &numElements, 0);
if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
{
result = _Keyboard->Acquire();
if (result != DI_OK) return;
// get device state
::GetKeyboardState((unsigned char *) _VKKeyState);
_LastDIKeyPressed = 0;
updateCtrlAltShiftValues();
result = _Keyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &datas[0], &numElements, 0);
if (result != DI_OK) return;
}
else if (result != DI_OK)
{
return;
}
_PollTime = (uint32) CTime::getLocalTime();
// process each message in the list
for (uint k = 0; k < numElements; ++k)
{
CDIEvent *die = new CDIEvent;
die->Emitter = this;
die->Datas = datas[k];
dev->submitEvent(die);
}
}
///========================================================================
void CDIKeyboard::transitionOccured(CEventServer *server, const IInputDeviceEvent *nextMessage)
{
repeatKey(buildDateFromEvent(nextMessage), server);
}
///========================================================================
TKeyButton CDIKeyboard::buildKeyButtonsFlags() const
{
return (TKeyButton) ( (ShiftPressed ? shiftKeyButton : 0)
| (CtrlPressed ? ctrlKeyButton : 0)
| (AltPressed ? altKeyButton : 0)
);
}
///========================================================================
void CDIKeyboard::keyTriggered(bool pressed, uint dikey, CEventServer *server, uint32 date)
{
#if 0
const uint numPairs = sizeof(DIToNel) / sizeof(CKeyConv);
for (uint k = 0; k < numPairs; ++k)
{
if (DIToNel[k].DIKey == key)
{
nlinfo(DIToNel[k].KeyName);
}
}
#endif
TKey keyValue, charValue;
updateVKKeyState(dikey, pressed, keyValue, charValue);
if (keyValue == 0) return;
CEventKey *ek;
if (pressed )
{
ek = new CEventKeyDown(keyValue, buildKeyButtonsFlags(), true, _DIEventEmitter);
}
else
{
ek = new CEventKeyUp(keyValue, buildKeyButtonsFlags(), _DIEventEmitter);
}
server->postEvent(ek);
if (pressed)
{
if (_RepetitionDisabled[(uint) keyValue] == false)
{
_LastEmitDate = _FirstPressDate = date;
_LastDIKeyPressed = dikey;
}
else // not a repeatable key
{
_LastDIKeyPressed = 0;
return;
}
}
else
{
// key released ?
if (dikey == _LastDIKeyPressed)
{
_LastDIKeyPressed = 0;
}
if (_RepetitionDisabled[(uint) keyValue] == true)
{
return;
}
}
// first char event (if repetition not disabled)
if (keyValue >= KeyNUMPAD0 && keyValue <= KeyNUMPAD9 || keyValue == KeyDECIMAL)
{
if ((_VKKeyState[KeyNUMLOCK] & 0x01) != 0)
{
sendUnicode(charValue, dikey, server, pressed);
}
}
else
{
sendUnicode(charValue, dikey, server, pressed);
}
_FirstPressDate = (uint32) NLMISC::CTime::getLocalTime(); // can't use the time stamp, because we can't not sure it matches the local time.
// time stamp is used for evenrts sorting only
}
///========================================================================
void CDIKeyboard::submit(IInputDeviceEvent *deviceEvent, CEventServer *server)
{
CDIEvent *die = safe_cast<CDIEvent *>(deviceEvent);
bool pressed = (die->Datas.dwData & 0x80) != 0;
keyTriggered(pressed, (uint) die->Datas.dwOfs, server, die->Datas.dwTimeStamp);
}
///========================================================================
TMouseButton CDIKeyboard::buildKeyboardButtonFlags() const
{
nlassert(_Keyboard);
return _DIEventEmitter->buildKeyboardButtonFlags();
}
///========================================================================
bool CDIKeyboard::setBufferSize(uint size)
{
nlassert(size > 0);
nlassert(_Keyboard);
_Keyboard->Unacquire();
DIPROPDWORD dipdw;
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = size;
HRESULT r = _Keyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph );
if (r != DI_OK) return false;
_KeyboardBufferSize = size;
return true;
}
///========================================================================
uint CDIKeyboard::getBufferSize() const
{
return _KeyboardBufferSize;
}
///========================================================================
TKey CDIKeyboard::DIKeyToNelKey(uint diKey, bool &extKey, bool &repeatable)
{
// some key are not handled by MapVirtualKeyEx so we need to convert them ourselves
static bool tableBuilt = false;
if (!tableBuilt)
{
uint k;
for (k = 0; k < NumKeys; ++k)
{
DIKeyToNelKeyTab[k] = NULL; // set as not a valid key by default
}
const uint numPairs = sizeof(DIToNel) / sizeof(CKeyConv);
for (k = 0; k < numPairs; ++k)
{
DIKeyToNelKeyTab[DIToNel[k].DIKey] = &DIToNel[k];
}
tableBuilt = true;
}
//
if (DIKeyToNelKeyTab[diKey] != NULL)
{
const CKeyConv &keyConv = *DIKeyToNelKeyTab[diKey];
extKey = true;
repeatable = keyConv.Repeatable;
return keyConv.NelKey;
}
// try doing the conversion using MapVirtualKey
TKey key = (TKey) ::MapVirtualKeyEx(diKey, 1, _KBLayout);
extKey = false;
return key;
}
///========================================================================
void CDIKeyboard::sendUnicode(TKey vkey, uint dikey, CEventServer *server, bool pressed)
{
uint8 oldShift = _VKKeyState[KeySHIFT];
/// If caps lock is off when pressing shift, we must disable shift, to get no minuscule letters when it is pressed and capslocks is on.
if (!_CapsLockToggle && _VKKeyState[KeyCAPITAL] & 0x01)
{
_VKKeyState[KeySHIFT] = 0;
}
// 'ToUnicode??' is supported since NT4.0 only
// Check if there's support
static bool init = false;
static bool toUnicodeSupported = false;
if (!init)
{
init = true;
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (::GetVersionEx (&osvi))
{
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
if (osvi.dwMajorVersion >= 4)
{
toUnicodeSupported = true;
}
}
}
}
if (toUnicodeSupported)
{
const uint maxNumKeys = 8;
WCHAR keyUnicodes[maxNumKeys];
int res = ::ToUnicodeEx(vkey, dikey | (pressed ? 0 : (1 << 15)), (unsigned char *) _VKKeyState, keyUnicodes, maxNumKeys, 0, _KBLayout);
//
_VKKeyState[KeySHIFT] = oldShift;
//
for (sint k = 0; k < res; ++k)
{
CEventChar *evc = new CEventChar((ucchar) keyUnicodes[k], buildKeyButtonsFlags(), _DIEventEmitter);
server->postEvent(evc);
}
}
else
{
unsigned char buf[2];
int res = ::ToAsciiEx(vkey, dikey | (pressed ? 0 : (1 << 15)), (unsigned char *) _VKKeyState, (LPWORD) buf, 0, _KBLayout);
for (sint k = 0; k < res; ++k)
{
CEventChar *evc = new CEventChar((ucchar) buf[k], buildKeyButtonsFlags(), _DIEventEmitter);
server->postEvent(evc);
}
}
}
///========================================================================
void CDIKeyboard::repeatKey(uint32 currentDate, CEventServer *server)
{
if (_LastDIKeyPressed == 0 || _LastDIKeyPressed == DIK_INSERT) return;
bool extKey;
bool repeatable;
TKey vkey = DIKeyToNelKey(_LastDIKeyPressed, extKey, repeatable);
if (vkey == 0) return;
if (currentDate - _FirstPressDate < _RepeatDelay) return;
sint32 firstDate = _LastEmitDate - (_FirstPressDate + _RepeatDelay);
sint32 lastDate = currentDate - (_FirstPressDate + _RepeatDelay);
if (firstDate < 0) firstDate = 0;
if (lastDate < firstDate) return;
uint numRep = (uint) ((lastDate + _RepeatPeriod - 1) / _RepeatPeriod - (firstDate + _RepeatPeriod - 1) / _RepeatPeriod);
//numRep = std::min(16u, numRep); // too much repetitions don't make sense...
if ((sint) numRep < 0) return; // 50 days loop..
numRep = 1; // fix : for now it seems better to limit the number of repetition to 1 per frame (it can be greater than 1 only if framerate is slow, but its not very useable)
// numpad case
if (vkey >= KeyNUMPAD0 && vkey <= KeyNUMPAD9 || vkey == KeyDECIMAL)
{
// check whether numlock is activated
if ((_VKKeyState[KeyNUMLOCK] & 0x01) != 0)
{
for (uint k = 0; k < numRep; ++k)
{
sendUnicode(vkey, _LastDIKeyPressed, server, true);
}
}
else
{
// arrow, home, end.. events
for (uint k = 0; k < numRep; ++k)
{
CEventKey *ek = new CEventKeyDown(vkey, buildKeyButtonsFlags(), false, _DIEventEmitter);
server->postEvent(ek);
}
}
}
else
{
for (uint k = 0; k < numRep; ++k)
{
// if it is an extended key, repetition won't be managed by sendUnicode
if (extKey && repeatable)
{
CEventKey *ek = new CEventKeyDown(vkey, buildKeyButtonsFlags(), false, _DIEventEmitter);
server->postEvent(ek);
}
else
{
sendUnicode(vkey, _LastDIKeyPressed, server, true);
}
}
}
_LastEmitDate = currentDate;
}
///========================================================================
uint32 CDIKeyboard::buildDateFromEvent(const IInputDeviceEvent *deviceEvent)
{
if (deviceEvent)
{
const CDIEvent *die = safe_cast<const CDIEvent *>(deviceEvent);
return (uint32) die->Datas.dwData;
}
else
{
return _PollTime;
}
}
///========================================================================
void CDIKeyboard::disableRepetition(const TKey *keyTab, uint numKey)
{
_RepetitionDisabled.clearAll();
for (uint k = 0; k < numKey; ++k)
{
_RepetitionDisabled.set((sint) keyTab[k]);
}
if (_LastDIKeyPressed != 0)
{
bool extKey;
bool repeatable;
TKey key = DIKeyToNelKey(_LastDIKeyPressed, extKey, repeatable);
if (_RepetitionDisabled[(uint) key])
{
// disable this key repetition
_LastDIKeyPressed = 0;
}
}
}
///========================================================================
uint CDIKeyboard::getNumDisabledRepetition() const
{
uint numKey = 0;
for (uint k = 0; k < NumKeys; ++k)
{
if (_RepetitionDisabled[k]) ++numKey;
}
return numKey;
}
///========================================================================
void CDIKeyboard::getDisabledRepetitions(TKey *destTab) const
{
for (uint k = 0; k < NumKeys; ++k)
{
if (_RepetitionDisabled[k]) *destTab++ = (TKey) k;
}
}
} // NLMISC
#endif // NL_OS_WINDOWS

View file

@ -1,163 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_DI_KEYBOARD_H
#define NL_DI_KEYBOARD_H
#include "nel/misc/types_nl.h"
#ifdef NL_OS_WINDOWS
#include "nel/misc/input_device_server.h"
#include "nel/misc/keyboard_device.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/bit_set.h"
namespace NLMISC
{
class CWinEventEmitter;
//
struct EDirectInputNoKeyboard : public EDirectInput
{
EDirectInputNoKeyboard() : EDirectInput("No keyboard found") {}
};
struct CKeyConv;
/**
* Direct Input implementation of a keyboard.
* \see CDIEventEmitter
* \author Nicolas Vizerie
* \author Nevrax France
* \date 2002
*/
class CDIKeyboard : public IKeyboardDevice
{
public:
bool ShiftPressed, CtrlPressed, AltPressed;
public:
///\name Object
//@{
/** Create a keyboard device, that must then be deleted by the caller
* An optional WinEventEmiter can be provided, so that its flags can be in sync
* with a win32 keyboard flags (shift, ctrl, and alt)
*/
static CDIKeyboard *createKeyboardDevice(IDirectInput8 *di8,
HWND hwnd,
CDIEventEmitter *diEventEmitter,
CWinEventEmitter *we = NULL
) throw(EDirectInput);
// dtor
virtual ~CDIKeyboard();
//@}
///\name From IInputDevice
//@{
virtual bool setBufferSize(uint size);
virtual uint getBufferSize() const;
//@}
///\name From IInputDevice
//@{
uint getKeyRepeatDelay() const { return _RepeatDelay; }
void setKeyRepeatDelay(uint delay) { nlassert(delay > 0); _RepeatDelay = delay; }
uint getKeyRepeatPeriod() const { return _RepeatPeriod; }
void setKeyRepeatPeriod(uint period) { nlassert(period > 0); _RepeatPeriod = period; }
void disableRepetition(const TKey *keyTab, uint numKey);
uint getNumDisabledRepetition() const;
void getDisabledRepetitions(TKey *destTab) const;
//@}
TMouseButton buildKeyboardFlags() const;
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
private:
//
bool _CapsLockToggle; // true if caps lock off is triggered by caps lock, false if it toggled by shift
uint _RepeatDelay; // the delay before a key is repeated (in ms)
uint _RepeatPeriod; // The period for key repetitions (in ms)
//
LPDIRECTINPUTDEVICE8 _Keyboard;
uint _KeyboardBufferSize;
// virtual code state
uint8 _VKKeyState[NumKeys];
// tells for which keys repetition is disabled
CBitSet _RepetitionDisabled;
// The date at which the last key pressed has been pressed (not using 64 bits since note handled by Direct Input)
uint32 _FirstPressDate;
// The last date at which key repetition occured (not using 64 bits since note handled by Direct Input)
uint32 _LastEmitDate;
// The system date at which the last polling occured (not using 64 bits since note handled by Direct Input)
uint32 _PollTime;
uint _LastDIKeyPressed;
CWinEventEmitter *_WE;
HWND _hWnd;
HKL _KBLayout;
//
CDIEventEmitter *_DIEventEmitter;
//
static const CKeyConv *DIKeyToNelKeyTab[NumKeys];
private:
/// ctor
CDIKeyboard(CWinEventEmitter *we, HWND hwnd);
/** Convert a direct input scancode to a virtual key. Note that DirectInput scancodes do not always match system scan codes.
* Repeatable has a meaning only for extended keys
*/
TKey DIKeyToNelKey(uint diKey, bool &extKey, bool &repeatable);
/** This update virtual key state table.
* \param keyValue contains the value to send to a EventKeyDown or EventKeyUp message.
* \param charValue contains the value that must be used for Unicode conversion (which generate EventChar messages)
*/
void updateVKKeyState(uint diKey, bool pressed, TKey &keyValue, TKey &charValue);
// Use the given virtual key code and the current keyb state to produce Unicode
void sendUnicode(TKey vkey, uint dikey, CEventServer *server, bool pressed);
// Build a TKeyButton value from the state of shift, ctrl and alt
TKeyButton buildKeyButtonsFlags() const;
// Update the state of this object and send the appropriate message when a direct / input key has been pressed / released
void keyTriggered(bool pressed, uint key, CEventServer *server, uint32 date);
// The same as buildKeyButtonsFlags(), but the return is a TMouseButtonValue (with no mouse value setupped)
TMouseButton buildKeyboardButtonFlags() const;
// setup the state of the Ctrl, Alt and Shift key from the state in the _VKKeyState buffer
void updateCtrlAltShiftValues();
/// Repeat the current key, and create events
void repeatKey(uint32 currentDate, CEventServer *server);
/// Build a date by using an event time stamp, or generate one if NULL
uint32 buildDateFromEvent(const IInputDeviceEvent *deviceEvent);
///\name From IInputDevice
//@{
virtual void poll(CInputDeviceServer *dev);
virtual void submit(IInputDeviceEvent *deviceEvent, CEventServer *server);
virtual void transitionOccured(CEventServer *server, const IInputDeviceEvent *nextMessage);
//@}
};
} // NLMISC
#endif // NL_OS_WINDOWS
#endif // NL_DI_KEYBOARD_H
/* End of di_keyboard.h */

View file

@ -1,507 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdmisc.h"
#include "di_mouse_device.h"
#include "nel/misc/game_device_events.h"
#include "nel/misc/win_event_emitter.h"
#ifdef NL_OS_WINDOWS
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
#ifdef NL_COMP_MINGW
# undef FIELD_OFFSET
# define FIELD_OFFSET(t,f) offsetof(t,f)
#endif
namespace NLMISC
{
//======================================================
CDIMouse::CDIMouse() : _MessageMode(RawMode),
_MouseSpeed(1.0f),
_MouseAccel(10000),
_Mouse(NULL),
_XAcc(0),
_YAcc(0),
_XMousePos(0),
_YMousePos(0),
_LastMouseButtonClicked(-1),
_DoubleClickDelay(300),
_XFactor(1.f),
_YFactor(1.f),
OldDIXPos(0),
OldDIYPos(0),
OldDIZPos(0),
_FirstX(true),
_FirstY(true),
_SwapButton(false)
{
std::fill(_MouseButtons, _MouseButtons + MaxNumMouseButtons, false);
std::fill(_MouseAxisMode, _MouseAxisMode + NumMouseAxis, Raw);
_MouseFrame.setWH(0, 0, 640, 480);
}
//======================================================
CDIMouse::~CDIMouse()
{
if (_Mouse)
{
_Mouse->Unacquire();
_Mouse->Release();
}
}
//======================================================
void CDIMouse::setMouseMode(TAxis axis, TAxisMode axisMode)
{
nlassert(axisMode < AxisModeLast);
nlassert(axis < AxisLast);
_MouseAxisMode[axis] = axisMode;
clampMouseAxis();
}
//======================================================
CDIMouse::TAxisMode CDIMouse::getMouseMode(TAxis axis) const
{
nlassert((int)axis < (int)NumMouseAxis);
return _MouseAxisMode[axis];
}
//======================================================
void CDIMouse::setMouseSpeed(float speed)
{
nlassert(_MessageMode == NormalMode);
nlassert(speed > 0);
_MouseSpeed = speed;
}
//======================================================
void CDIMouse::setMouseAcceleration(uint accel)
{
_MouseAccel = accel;
}
//======================================================
uint CDIMouse::getMouseAcceleration() const
{
return _MouseAccel;
}
//======================================================
bool CDIMouse::setBufferSize(uint size)
{
nlassert(size > 0);
nlassert(_Mouse);
_Mouse->Unacquire();
DIPROPDWORD dipdw;
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = size;
HRESULT r = _Mouse->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph );
if (r != DI_OK) return false;
_MouseBufferSize = size;
return true;
}
//======================================================
uint CDIMouse::getBufferSize() const { return _MouseBufferSize; }
//======================================================
void CDIMouse::setMousePos(float x, float y)
{
nlassert(_MessageMode == NormalMode);
_XMousePos = (sint64) ((double) x * ((sint64) 1 << 32));
_YMousePos = (sint64) ((double) y * ((sint64) 1 << 32));
}
//======================================================
CDIMouse *CDIMouse::createMouseDevice(IDirectInput8 *di8, HWND hwnd, CDIEventEmitter *diEventEmitter, bool hardware, CWinEventEmitter *we) throw(EDirectInput)
{
std::auto_ptr<CDIMouse> mouse(new CDIMouse);
mouse->_DIEventEmitter = diEventEmitter;
mouse->_Hardware = hardware;
HRESULT result = di8->CreateDevice(GUID_SysMouse, &(mouse->_Mouse), NULL);
if (result != DI_OK) throw EDirectInputNoMouse();
result = mouse->_Mouse->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | (!hardware ? DISCL_EXCLUSIVE:DISCL_NONEXCLUSIVE));
if (result != DI_OK) throw EDirectInputCooperativeLevelFailed();
mouse->_Mouse->SetDataFormat(&c_dfDIMouse2);
mouse->setBufferSize(64);
mouse->_WE = we;
mouse->setDoubleClickDelay(::GetDoubleClickTime());
/** we want an absolute mouse mode, so that, if the event buffer get full, we can retrieve the right position
*/
DIPROPDWORD prop;
prop.diph.dwSize = sizeof(DIPROPDWORD);
prop.diph.dwHeaderSize = sizeof(DIPROPHEADER);
prop.diph.dwHow = DIPH_DEVICE;
prop.diph.dwObj = 0;
prop.dwData = DIPROPAXISMODE_ABS;
HRESULT r = mouse->_Mouse->SetProperty(DIPROP_AXISMODE, &prop.diph);
nlassert(r == DI_OK); // should always succeed...
//
mouse->_Mouse->Acquire();
mouse->_hWnd = hwnd;
// Enable win32 mouse message only if hardware mouse in normal mode
if (mouse->_WE)
mouse->_WE->enableMouseEvents(mouse->_Hardware && (mouse->_MessageMode == IMouseDevice::NormalMode));
mouse->_SwapButton = GetSystemMetrics(SM_SWAPBUTTON) != 0;
return mouse.release();
}
//======================================================
float CDIMouse::getMouseSpeed() const
{
nlassert(_MessageMode == NormalMode);
return _MouseSpeed;
}
//======================================================
const CRect &CDIMouse::getMouseFrame() const
{
nlassert(_MessageMode == NormalMode);
return _MouseFrame;
}
//======================================================
uint CDIMouse::getDoubleClickDelay() const { return _DoubleClickDelay; }
//======================================================
inline void CDIMouse::clampMouseAxis()
{
if (_MouseAxisMode[XAxis] == Clamped) clamp(_XMousePos, (sint64) _MouseFrame.X << 32, (sint64) (_MouseFrame.X + _MouseFrame.Width - 1) << 32);
if (_MouseAxisMode[YAxis] == Clamped) clamp(_YMousePos, (sint64) _MouseFrame.Y << 32, (sint64) (_MouseFrame.X + _MouseFrame.Height - 1) << 32);
}
//======================================================
void CDIMouse::poll(CInputDeviceServer *dev)
{
nlassert(_Mouse);
nlassert(_MouseBufferSize > 0);
static std::vector<DIDEVICEOBJECTDATA> datas;
datas.resize(_MouseBufferSize);
DWORD numElements = _MouseBufferSize;
HRESULT result = _Mouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &datas[0], &numElements, 0);
if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
{
result = _Mouse->Acquire();
HRESULT result = _Mouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &datas[0], &numElements, 0);
if (result != DI_OK) return;
}
else if (result != DI_OK) return;
if (::IsWindowEnabled(_hWnd) && ::IsWindowVisible(_hWnd))
{
for(uint k = 0; k < numElements; ++k)
{
CDIEvent *die = new CDIEvent;
die->Emitter = this;
die->Datas = datas[k];
dev->submitEvent(die);
}
}
}
//======================================================================
TMouseButton CDIMouse::buildMouseButtonFlags() const
{
if (_SwapButton)
return (TMouseButton) (
_DIEventEmitter->buildKeyboardButtonFlags()
| (_MouseButtons[0] ? rightButton : 0)
| (_MouseButtons[1] ? leftButton : 0)
| (_MouseButtons[2] ? middleButton : 0)
);
else
return (TMouseButton) (
_DIEventEmitter->buildKeyboardButtonFlags()
| (_MouseButtons[0] ? leftButton : 0)
| (_MouseButtons[1] ? rightButton : 0)
| (_MouseButtons[2] ? middleButton : 0)
);
}
//======================================================
TMouseButton CDIMouse::buildMouseSingleButtonFlags(uint button)
{
static const TMouseButton mb[] = { leftButton, rightButton, middleButton };
static const TMouseButton mbswap[] = { rightButton, leftButton, middleButton };
nlassert(button < MaxNumMouseButtons);
if (_SwapButton)
return (TMouseButton) (_DIEventEmitter->buildKeyboardButtonFlags() | mbswap[button]);
else
return (TMouseButton) (_DIEventEmitter->buildKeyboardButtonFlags() | mb[button]);
}
//======================================================
void CDIMouse::onButtonClicked(uint button, CEventServer *server, uint32 date)
{
// check for double click
if (_LastMouseButtonClicked == (sint) button)
{
if (date - _MouseButtonsLastClickDate < _DoubleClickDelay)
{
CEventMouseDblClk *emdc
= new CEventMouseDblClk((float) (_XMousePos >> 32),
(float) (_YMousePos >> 32),
buildMouseSingleButtonFlags(button),
_DIEventEmitter);
server->postEvent(emdc);
_LastMouseButtonClicked = -1;
}
else
{
_MouseButtonsLastClickDate = date;
}
}
else
{
_LastMouseButtonClicked = button;
_MouseButtonsLastClickDate = date;
}
}
//======================================================
void CDIMouse::processButton(uint button, bool pressed, CEventServer *server, uint32 date)
{
updateMove(server);
float mx = (float) (_XFactor * (double) _XMousePos / ((double) 65536 * (double) 65536));
float my = (float) (_YFactor * (double) _YMousePos / ((double) 65536 * (double) 65536));
if (pressed)
{
CEventMouseDown *emd =
new CEventMouseDown(mx, my, buildMouseSingleButtonFlags(button),
_DIEventEmitter);
server->postEvent(emd);
}
else
{
CEventMouseUp *emu =
new CEventMouseUp(mx, my, buildMouseSingleButtonFlags(button), _DIEventEmitter);
server->postEvent(emu);
onButtonClicked(button, server, date);
}
_MouseButtons[button] = pressed;
}
//======================================================
void CDIMouse::submit(IInputDeviceEvent *deviceEvent, CEventServer *server)
{
if (!_Hardware || (_MessageMode == RawMode))
{
CDIEvent *die = safe_cast<CDIEvent *>(deviceEvent);
bool pressed;
switch(die->Datas.dwOfs)
{
case DIMOFS_X:
{
if (!_FirstX)
{
sint dep = (sint32) die->Datas.dwData - OldDIXPos;
// Acceleration
if (_MouseAccel)
{
sint accelFactor = abs (dep) / (sint)_MouseAccel;
dep <<= accelFactor;
}
_XAcc += dep;
}
else
{
_FirstX = false;
}
OldDIXPos = (sint32) die->Datas.dwData;
}
break;
case DIMOFS_Y:
{
if (!_FirstY)
{
sint dep = (sint32) die->Datas.dwData - OldDIYPos;
// Acceleration
if (_MouseAccel)
{
sint accelFactor = abs (dep) / (sint)_MouseAccel;
dep <<= accelFactor;
}
_YAcc -= dep;
}
else
{
_FirstY = false;
}
OldDIYPos = (sint32) die->Datas.dwData;
}
break;
case DIMOFS_Z:
{
updateMove(server);
sint dep = die->Datas.dwData - OldDIZPos;
OldDIZPos = (sint32) die->Datas.dwData;
CEventMouseWheel *emw =
new CEventMouseWheel((float) (_XMousePos >> 32),
(float) (_XMousePos >> 32),
buildMouseButtonFlags(),
dep > 0,
_DIEventEmitter);
server->postEvent(emw);
}
break;
case DIMOFS_BUTTON0: /* left button */
pressed = (die->Datas.dwData & 0x80) != 0;
processButton(0, pressed, server, die->Datas.dwTimeStamp);
break;
case DIMOFS_BUTTON1: /* right button */
pressed = (die->Datas.dwData & 0x80) != 0;
processButton(1, pressed, server, die->Datas.dwTimeStamp);
break;
case DIMOFS_BUTTON2: /* middle button */
pressed = (die->Datas.dwData & 0x80) != 0;
processButton(2, pressed, server, die->Datas.dwTimeStamp);
break;
default:
return;
break;
}
}
}
//======================================================
void CDIMouse::updateMove(CEventServer *server)
{
if (_XAcc != 0 || _YAcc != 0)
{
if (_MessageMode == NormalMode)
{
_XMousePos += (sint64) ((double) _MouseSpeed * (sint64) _XAcc * ((sint64) 1 << 32));
_YMousePos += (sint64) ((double) _MouseSpeed * (sint64) _YAcc * ((sint64) 1 << 32));
clampMouseAxis();
CEventMouseMove *emm = new CEventMouseMove((float) (_XFactor * (double) _XMousePos / ((double) 65536 * (double) 65536)), (float) (_YFactor * (double) _YMousePos / ((double) 65536 * (double) 65536)), buildMouseButtonFlags(), _DIEventEmitter);
server->postEvent(emm);
}
else
{
CGDMouseMove *emm = new CGDMouseMove(_DIEventEmitter, this, _XAcc, _YAcc);
server->postEvent(emm);
}
_XAcc = _YAcc = 0;
}
}
//======================================================
void CDIMouse::convertStdMouseMoveInMickeys(float &dx, float &dy) const
{
// get in same scale as _XAcc and _YAcc
double xacc= ((double)dx/_XFactor) / _MouseSpeed;
double yacc= ((double)dy/_YFactor) / _MouseSpeed;
dx= float(xacc);
dy =float(yacc);
}
//======================================================
void CDIMouse::transitionOccured(CEventServer *server, const IInputDeviceEvent *)
{
updateMove(server);
}
//======================================================
void CDIMouse::setButton(uint button, bool pushed)
{
nlassert(button < MaxNumMouseButtons);
_MouseButtons[button] = pushed;
}
//======================================================
bool CDIMouse::getButton(uint button) const
{
nlassert(button < MaxNumMouseButtons);
return _MouseButtons[button];
}
//======================================================
void CDIMouse::setDoubleClickDelay(uint ms)
{
nlassert(ms > 0);
_DoubleClickDelay = ms;
}
//======================================================
void CDIMouse::setMouseFrame(const CRect &rect)
{
nlassert(_MessageMode == NormalMode);
_MouseFrame = rect;
}
//======================================================
void CDIMouse::setMessagesMode(TMessageMode mode)
{
nlassert(mode < MessageModeLast);
_MessageMode = mode;
_FirstX = _FirstY = true;
// Enable win32 mouse message only if hardware mouse in normal mode
if (_WE)
_WE->enableMouseEvents(_Hardware && (_MessageMode == NormalMode));
}
} // NLMISC
#endif // NL_OS_WINDOWS

View file

@ -1,167 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_DI_MOUSE_DEVICE_H
#define NL_DI_MOUSE_DEVICE_H
#include "nel/misc/types_nl.h"
#ifdef NL_OS_WINDOWS
#include "nel/misc/rect.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/misc/input_device_server.h"
#include "nel/misc/mouse_device.h"
#include <dinput.h>
namespace NLMISC
{
//
struct EDirectInputNoMouse : public EDirectInput
{
EDirectInputNoMouse() : EDirectInput("No mouse found") {}
};
class CDXEventEmitter;
/**
* Direct Input implementation of a mouse
* \see CDIEventEmitter
* \author Nicolas Vizerie
* \author Nevrax France
* \date 2002
*/
class CDIMouse : public IMouseDevice
{
public:
enum { MaxNumMouseButtons = 3, NumMouseAxis = 3};
public:
///\name Object
//@{
virtual ~CDIMouse();
/** Create a mouse device from a valid DirectInput8 pointer. This must then be deleted by the caller.
* \return the interface or throw an exception if the creation failed
*/
static CDIMouse *createMouseDevice(IDirectInput8 *di8, HWND hwnd, CDIEventEmitter *diEventEmitter, bool hardware, class CWinEventEmitter *we) throw(EDirectInput);
//@}
///\name Mouse params, inherited from IMouseDevice
//@{
void setMessagesMode(TMessageMode mode);
TMessageMode getMessagesMode() const { return _MessageMode; }
void setMouseMode(TAxis axis, TAxisMode axisMode);
TAxisMode getMouseMode(TAxis axis) const;
void setMouseSpeed(float speed);
float getMouseSpeed() const;
void setMouseAcceleration(uint speed);
uint getMouseAcceleration() const;
void setMouseFrame(const CRect &rect);
const CRect &getMouseFrame() const;
void setDoubleClickDelay(uint ms);
uint getDoubleClickDelay() const;
void setMousePos(float x, float y);
void setFactors(float xFactor, float yFactor)
{
nlassert(_MessageMode == NormalMode);
_XFactor = xFactor;
_YFactor = yFactor;
}
float getXFactor() const { nlassert(_MessageMode == NormalMode); return _XFactor; }
float getYFactor() const { nlassert(_MessageMode == NormalMode); return _YFactor; }
void convertStdMouseMoveInMickeys(float &dx, float &dy) const;
//@}
///\name From IInputDevice
//@{
virtual bool setBufferSize(uint size);
virtual uint getBufferSize() const;
//@}
///\name From IInputDevice
//@{
void setButton(uint button, bool pushed);
bool getButton(uint button) const;
//@}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
private:
LPDIRECTINPUTDEVICE8 _Mouse;
//
bool _Hardware;
//
TMessageMode _MessageMode;
//
TAxisMode _MouseAxisMode[NumMouseAxis];
sint64 _XMousePos, _YMousePos; // position encoded in fixed point 32 : 32. This allow wrapping and no loss of precision, when not in clamped mode
// NB: this is sint64 because of max range reached with 16:16 when looping around x with great mouse speed
bool _FirstX, _FirstY;
float _MouseSpeed;
uint _MouseAccel;
CRect _MouseFrame;
//
bool _MouseButtons[MaxNumMouseButtons];
uint32 _MouseButtonsLastClickDate;
sint _LastMouseButtonClicked;
uint _DoubleClickDelay;
uint _MouseBufferSize;
HWND _hWnd;
//
sint32 OldDIXPos, OldDIYPos, OldDIZPos; // old positions reported by direct input
sint _XAcc, _YAcc; // accumulate move (needed because they are generated on a single axis for each DI event)
float _XFactor, _YFactor;
//
CDIEventEmitter *_DIEventEmitter;
// The windows emitter to enable / disble win32 mouse messages
NLMISC::CRefPtr<CWinEventEmitter> _WE;
// Does the button left and right are swapped ?
bool _SwapButton;
private:
/// ctor
CDIMouse();
/// Clamp the mouse axis that need to be.
void clampMouseAxis();
/// Sum the mouse move and produce an event
void updateMove(CEventServer *server);
void processButton(uint button, bool pressed, CEventServer *server, uint32 date);
TMouseButton buildMouseButtonFlags() const;
TMouseButton buildMouseSingleButtonFlags(uint button);
void onButtonClicked(uint button, CEventServer *server, uint32 date);
///\name From IInputDevice
//@{
virtual void poll(CInputDeviceServer *dev);
virtual void submit(IInputDeviceEvent *deviceEvent, CEventServer *server);
virtual void transitionOccured(CEventServer *server, const IInputDeviceEvent *nextMessage);
//@}
};
} // NL3D
#endif // NL_OS_WINDOWS
#endif // NL_DI_MOUSE_H
/* End of di_mouse.h */

View file

@ -84,11 +84,6 @@ void CEventEmitterMulti::submitEvents(CEventServer &server, bool allWindows)
}
}
///============================================================
void CEventEmitterMulti::emulateMouseRawMode(bool enable)
{
}
///============================================================
IEventEmitter *CEventEmitterMulti::getEmitter(uint index)
{

View file

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

View file

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

View file

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

View file

@ -1,109 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdmisc.h"
#include "nel/misc/input_device_server.h"
#include "nel/misc/input_device.h"
#include "nel/misc/debug.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
namespace NLMISC
{
//=======================================================================
void CInputDeviceServer::registerDevice(IInputDevice *device)
{
nlassert(!isDevice(device));
_Devices.push_back(device);
}
//=======================================================================
void CInputDeviceServer::removeDevice(IInputDevice *device)
{
TDeviceCont::iterator it = std::find(_Devices.begin(), _Devices.end(), device);
nlassert(it != _Devices.end());
_Devices.erase(it);
}
//=======================================================================
bool CInputDeviceServer::isDevice(IInputDevice *device) const
{
TDeviceCont::const_iterator it = std::find(_Devices.begin(), _Devices.end(), device);
return it != _Devices.end();
}
//=======================================================================
// Predicate to compare vents dates
struct CInputDeviceEventLess
{
bool operator()(const IInputDeviceEvent *lhs, const IInputDeviceEvent *rhs) const
{
return *lhs < *rhs;
}
};
//=======================================================================
void CInputDeviceServer::poll(CEventServer *server)
{
nlassert(_Events.empty());
TDeviceCont::iterator deviceIt;
for (deviceIt = _Devices.begin(); deviceIt != _Devices.end(); ++deviceIt)
{
(*deviceIt)->begin(server);
(*deviceIt)->poll(this);
}
// Sort the messages to get the right dates.
std::sort(_Events.begin(), _Events.end(), CInputDeviceEventLess());
// submit the result to the server
IInputDevice *lastVisitedDevice = NULL;
TEventCont::iterator eventIt;
for (eventIt = _Events.begin(); eventIt != _Events.end(); ++eventIt)
{
// see if this message is from a previous device then the last we visited.
if (lastVisitedDevice && (*eventIt)->Emitter != lastVisitedDevice)
{
// yes, tells that a transition occured
lastVisitedDevice->transitionOccured(server, *eventIt);
lastVisitedDevice = (*eventIt)->Emitter;
}
nlassert((*eventIt)->Emitter != NULL);
(*eventIt)->Emitter->submit(*eventIt, server);
}
//
for (deviceIt = _Devices.begin(); deviceIt != _Devices.end(); ++deviceIt)
{
(*deviceIt)->transitionOccured(server, NULL);
}
// delete the messages
for (eventIt = _Events.begin(); eventIt != _Events.end(); ++eventIt)
{
delete *eventIt;
}
//
_Events.clear();
}
//=======================================================================
void CInputDeviceServer::submitEvent(IInputDeviceEvent *deviceEvent)
{
_Events.push_back(deviceEvent);
}
} // NLMISC

View file

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

View file

@ -57,14 +57,6 @@ void CWinEventEmitter::submitEvents(CEventServer & server, bool allWindows)
_InternalServer.pump (allWindows);
}
/*------------------------------------------------------------------*\
emulateMouseRawMode()
\*------------------------------------------------------------------*/
void CWinEventEmitter::emulateMouseRawMode(bool enable)
{
nlerror("no raw mode emulation on windows, the CDIMouse has a real raw mode");
}
/*------------------------------------------------------------------*\
processMessage()
\*------------------------------------------------------------------*/
@ -320,7 +312,7 @@ bool CWinEventEmitter::processMessage (HWND hWnd, uint32 msg, WPARAM wParam, LPA
case WM_INPUTLANGCHANGE:
if ( _IMEEventsEnabled )
{
// wParam = Specifies the character set of the new locale.
// wParam = Specifies the character set of the new locale.
// lParam = Input locale identifier.
server->postEvent( new CEventIME( msg, (uint32)wParam, (uint32)lParam, this ) );
return true; // trap message

View file

@ -214,6 +214,12 @@ Shadows_ps1 = 1;
Shadows_ps2 = 1;
Shadows_ps3 = 1;
FXAA = 1;
FXAA_ps0 = 0;
FXAA_ps1 = 1;
FXAA_ps2 = 1;
FXAA_ps3 = 1;
Bloom = 0;
Bloom_ps0 = 0;
Bloom_ps1 = 1;

View file

@ -210,6 +210,12 @@ Shadows_ps1 = 1;
Shadows_ps2 = 1;
Shadows_ps3 = 1;
FXAA = 1;
FXAA_ps0 = 0;
FXAA_ps1 = 1;
FXAA_ps2 = 1;
FXAA_ps3 = 1;
Bloom = 0;
Bloom_ps0 = 0;
Bloom_ps1 = 1;

View file

@ -1230,8 +1230,15 @@
posref="BL TL"
x="-20"
y="-12" />
<instance template="tgcw_checkbox"
id="fxaa"
text="uiFXAA"
posparent="shadow"
posref="BL TL"
x="0"
y="-12" />
<group id="bloom_gr"
posparent="shadow"
posparent="fxaa"
sizeparent="parent"
sizeref="w"
h="100"
@ -3133,6 +3140,12 @@
realtime="true"
link="Shadows"
preset="UI:TEMP:PRESET_FX" />
<param ui="fx:fxaa:c"
type="cfg"
widget="boolbut"
realtime="true"
link="FXAA"
preset="UI:TEMP:PRESET_FX" />
<param ui="fx:bloom_gr:bloom:c"
type="cfg"
widget="boolbut"

View file

@ -349,13 +349,6 @@ CClientConfig::CClientConfig()
ForceDeltaTime = 0; // Default ForceDeltaTime, disabled by default
#ifdef NL_OS_WINDOWS
DisableDirectInput = false; // Default DisableDirectInput
#else
DisableDirectInput = true; // no direct input on linux
#endif
DisableDirectInputKeyboard = true; // Default DisableDirectInput fort he keyboard only
HardwareCursor = true; // Default HardwareCursor
HardwareCursorScale = 0.85f;
CursorSpeed = 1.f; // Default CursorSpeed
@ -396,6 +389,8 @@ CClientConfig::CClientConfig()
Fog = true; // Fog is on by default
WaitVBL = false;
FXAA = true;
Bloom = true;
SquareBloom = true;
DensityBloom = 255.f;
@ -857,8 +852,6 @@ void CClientConfig::setValues()
////////////
// INPUTS //
READ_BOOL_FV(DisableDirectInput)
READ_BOOL_FV(DisableDirectInputKeyboard)
READ_BOOL_FV(HardwareCursor)
READ_FLOAT_FV(HardwareCursorScale)
READ_FLOAT_FV(CursorSpeed)
@ -989,6 +982,9 @@ void CClientConfig::setValues()
READ_BOOL_FV(SquareBloom)
READ_FLOAT_FV(DensityBloom)
// FXAA
READ_BOOL_FV(FXAA)
// ScreenAspectRatio.
READ_FLOAT_FV(ScreenAspectRatio)
// FoV.
@ -1969,16 +1965,16 @@ void CClientConfig::init(const string &configFileName)
size_t endOfLine = contentUtf8.find("\n", pos);
contentUtf8.erase(pos, (endOfLine - pos) + 1);
}
// get current location of the root config file (client_default.cfg)
std::string defaultConfigLocation;
if(!getDefaultConfigLocation(defaultConfigLocation))
nlerror("cannot find client_default.cfg");
// and store it in the RootConfigFilename value in the very first line
contentUtf8.insert(0, std::string("RootConfigFilename = \"") +
contentUtf8.insert(0, std::string("RootConfigFilename = \"") +
defaultConfigLocation + "\";\n");
// save the updated config file
NLMISC::COFile configFile(configFileName, false, true, false);
configFile.serialBuffer((uint8*)contentUtf8.c_str(), (uint)contentUtf8.size());
@ -2206,13 +2202,13 @@ ucstring CClientConfig::buildLoadingString( const ucstring& ucstr ) const
}
// ***************************************************************************
bool CClientConfig::getDefaultConfigLocation(std::string& p_name) const
bool CClientConfig::getDefaultConfigLocation(std::string& p_name) const
{
std::string defaultConfigFileName = "client_default.cfg";
std::string defaultConfigPath;
p_name.clear();
#ifdef NL_OS_MAC
// on mac, client_default.cfg should be searched in .app/Contents/Resources/
defaultConfigPath = CPath::standardizePath(getAppBundlePath() + "/Contents/Resources/");

View file

@ -78,7 +78,7 @@ struct CClientConfig
sint SelectCharacter;
/// Selected slot in select char interface
uint8 SelectedSlot;
/// Textures for interface login
std::vector<string> TexturesLoginInterface;
std::vector<string> TexturesLoginInterfaceDXTC;
@ -190,8 +190,6 @@ struct CClientConfig
/// \name Inputs
/// Use a hardware cursor
bool DisableDirectInput;
bool DisableDirectInputKeyboard;
bool HardwareCursor;
float HardwareCursorScale; // scale for hardware cursor bitmap (in ]0, 1])
float CursorSpeed;
@ -265,6 +263,9 @@ struct CClientConfig
float GlobalWindPower;
CVector GlobalWindDirection;
// FXAA
bool FXAA;
// Is bloom effect activated
bool Bloom;
bool SquareBloom;

View file

@ -31,6 +31,7 @@
// 3D Interface.
#include "nel/3d/u_driver.h"
#include "nel/3d/u_text_context.h"
#include <nel/3d/stereo_display.h>
// Game Share
//#include "game_share/gd_time.h" // \todo GUIGUI : TO DELETE/CHANGE
#include "game_share/gender.h"
@ -116,6 +117,8 @@ extern void saveMovieShooting();
extern void displaySpecialTextProgress(const char *text);
extern bool InitMouseWithCursor(bool hardware);
extern bool SetMousePosFirstTime;
/////////////
// Globals // initialization occurs in the function : connection
/////////////
@ -203,9 +206,13 @@ void connectionRestaureVideoMode ()
if (ClientCfg.Width < 800) ClientCfg.Width = 800;
if (ClientCfg.Height < 600) ClientCfg.Height = 600;
if ((ClientCfg.Windowed != mode.Windowed) ||
if (StereoDisplay)
StereoDisplayAttached = StereoDisplay->attachToDisplay();
if (!StereoDisplayAttached && (
(ClientCfg.Windowed != mode.Windowed) ||
(ClientCfg.Width != mode.Width) ||
(ClientCfg.Height != mode.Height))
(ClientCfg.Height != mode.Height)))
{
mode.Windowed = ClientCfg.Windowed;
mode.Depth = uint8(ClientCfg.Depth);
@ -216,7 +223,7 @@ void connectionRestaureVideoMode ()
}
// And setup hardware mouse if we have to
InitMouseWithCursor (ClientCfg.HardwareCursor);
InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached);
SetMouseFreeLook ();
SetMouseCursor ();
SetMouseSpeed (ClientCfg.CursorSpeed);
@ -251,6 +258,10 @@ void setOutGameFullScreen()
// NB: don't setup fullscreen if player wants to play in window
if (!ClientCfg.Local && ClientCfg.SelectCharacter == -1)
{
if (StereoDisplayAttached)
StereoDisplay->detachFromDisplay();
StereoDisplayAttached = false;
UDriver::CMode currMode;
Driver->getCurrentScreenMode(currMode);
UDriver::CMode wantedMode;
@ -267,6 +278,8 @@ void setOutGameFullScreen()
{
setVideoMode(wantedMode);
}
InitMouseWithCursor(ClientCfg.HardwareCursor && !StereoDisplayAttached);
/*
InitMouseWithCursor (true);
Driver->showCursor(false);
@ -385,7 +398,7 @@ bool connection (const string &cookie, const string &fsaddr)
// not initialized at login and remain hardware until here ...
// Re-initialise the mouse (will be now in hardware mode, if required)
//InitMouseWithCursor (ClientCfg.HardwareCursor); // the return value of enableLowLevelMouse() has already been tested at startup
//InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached); // the return value of enableLowLevelMouse() has already been tested at startup
// no ui init if character selection is automatic
//SetMouseFreeLook ();
@ -544,7 +557,8 @@ bool reconnection()
if (ClientCfg.SelectCharacter == -1)
{
// Re-initialise the mouse (will be now in hardware mode, if required)
InitMouseWithCursor (ClientCfg.HardwareCursor); // the return value of enableLowLevelMouse() has already been tested at startup
SetMousePosFirstTime = true;
InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached); // the return value of enableLowLevelMouse() has already been tested at startup
// no ui init if character selection is automatic
SetMouseFreeLook ();

View file

@ -21,7 +21,6 @@
#include "events_listener.h"
#include "nel/misc/events.h"
#include "nel/misc/game_device_events.h"
#include "nel/misc/event_server.h"
#include "release.h"
#include "actions.h"
@ -29,11 +28,13 @@
#include "time_client.h"
#include "input.h"
#include "interface_v3/interface_manager.h"
#include "global.h"
using namespace NLMISC;
extern CActionsManager Actions; // Actions Manager.
extern bool MouseFreeLook;
//---------------------------------------------------
// CEventsListener :
@ -82,7 +83,6 @@ CEventsListener::~CEventsListener()
//---------------------------------------------------
void CEventsListener::addToServer(CEventServer& server)
{
server.addListener(EventGDMouseMove, this);
server.addListener(EventMouseMoveId, this);
server.addListener(EventMouseDownId, this);
server.addListener(EventMouseUpId, this);
@ -101,7 +101,6 @@ void CEventsListener::addToServer(CEventServer& server)
//---------------------------------------------------
void CEventsListener::removeFromServer (CEventServer& server)
{
server.removeListener(EventGDMouseMove, this);
server.removeListener(EventMouseMoveId, this);
server.removeListener(EventMouseDownId, this);
server.removeListener(EventMouseUpId, this);
@ -113,6 +112,12 @@ void CEventsListener::removeFromServer (CEventServer& server)
server.removeListener(EventSetFocusId, this);
}// removeFromServer //
static bool s_MouseFreeLookReady = false;
static sint s_MouseFreeLookLastX;
static sint s_MouseFreeLookLastY;
static sint s_MouseFreeLookFrameX = 0;
static sint s_MouseFreeLookFrameY = 0;
static bool s_MouseFreeLookWaitCenter;
//---------------------------------------------------
// operator() :
@ -148,20 +153,64 @@ void CEventsListener::operator()(const CEvent& event)
{
CAHManager::getInstance()->runActionHandler("enter_modal", NULL, "group=ui:interface:quit_dialog");
}
// Event from the Mouse (ANGLE)
if(event == EventGDMouseMove)
{
CGDMouseMove* mouseEvent=(CGDMouseMove*)&event;
// Mouse acceleration
sint dX = mouseEvent->X;
sint dY = ClientCfg.FreeLookInverted ? -mouseEvent->Y : mouseEvent->Y;
updateFreeLookPos((float) dX, (float) dY);
}
// Event from the Mouse (MOVE)
else if(event == EventMouseMoveId)
{
CEventMouseMove* mouseEvent=(CEventMouseMove*)&event;
updateCursorPos(mouseEvent->X, mouseEvent->Y);
if (!MouseFreeLook)
{
updateCursorPos(mouseEvent->X, mouseEvent->Y);
s_MouseFreeLookReady = false;
}
else
{
// Get in pixel space, centered
uint32 drW, drH;
Driver->getWindowSize(drW, drH);
float fX = mouseEvent->X; // from 0 to 1.0
float fY = (ClientCfg.FreeLookInverted ? -mouseEvent->Y : mouseEvent->Y);
sint scX = (sint32)(fX * (float)drW) - ((sint32)drW >> 1); // in pixels, centered
sint scY = (sint32)(fY * (float)drH) - ((sint32)drH >> 1);
if (!s_MouseFreeLookReady)
{
float pfX = _MouseX;
float pfY = (ClientCfg.FreeLookInverted ? -_MouseY : _MouseY);
sint pscX = (sint32)(pfX * (float)drW) - ((sint32)drW >> 1); // in pixels, centered
sint pscY = (sint32)(pfY * (float)drH) - ((sint32)drH >> 1);
s_MouseFreeLookReady = true;
s_MouseFreeLookLastX = pscX;
s_MouseFreeLookLastY = pscY;
s_MouseFreeLookWaitCenter = false;
}
// NOTE: No 0, 0 center mouse message in Windows (lower mouse message rate), but safe to assume any movement messages are requeued relative to our new position
// In case free look bugs on other platform, we may need to push in our own message on setMousePos for Windows
if (s_MouseFreeLookWaitCenter) // scX == 0 && scY == 0)
{
// Centered, set last to 0
s_MouseFreeLookLastX = 0;
s_MouseFreeLookLastY = 0;
s_MouseFreeLookWaitCenter = false;
}
// Get delta since last center
sint scXd = scX - s_MouseFreeLookLastX;
sint scYd = scY - s_MouseFreeLookLastY;
s_MouseFreeLookLastX = scX;
s_MouseFreeLookLastY = scY;
s_MouseFreeLookFrameX += scXd;
s_MouseFreeLookFrameY += scYd;
// updateFreeLookPos is called in updateMouseSmoothing per frame
// Center cursor
bool outsideBounds = ((abs(scX) > (drW >> 3)) || (abs(scY) > (drH >> 3)));
if (outsideBounds)
{
s_MouseFreeLookWaitCenter = true;
Driver->setMousePos(0.5f, 0.5f);
}
}
}
// Event from the Mouse (DOWN BUTTONS)
else if(event == EventMouseDownId)
@ -233,16 +282,9 @@ void CEventsListener::updateMouseSmoothing()
{
if (_LastFreeLookUpdateDate != TimeInSec)
{
if (ClientCfg.FreeLookSmoothingPeriod != 0.f && _MouseSmoothingOn)
{
// free look hasn't been updated that frame because there was no
// mouse move msg.
// mouse pos must be updated however because of smoothing
updateFreeLookPos(0, 0);
}
updateFreeLookPos((float)s_MouseFreeLookFrameX, (float)s_MouseFreeLookFrameY);
s_MouseFreeLookFrameX = 0;
s_MouseFreeLookFrameY = 0;
}
}
@ -267,7 +309,6 @@ void CEventsListener::enableMouseSmoothing(bool on)
// ***************************************************************
void CEventsListener::updateFreeLookPos(float x, float y)
{
if (ClientCfg.FreeLookSmoothingPeriod == 0 || !_MouseSmoothingOn)
{
_MouseDeltaAX = x * ClientCfg.FreeLookSpeed;

View file

@ -25,21 +25,25 @@ using namespace NLMISC;
// ***************************************************************************
// Main System
NL3D::UDriver *Driver = 0; // The main 3D Driver
NL3D::UDriver *Driver = NULL; // The main 3D Driver
NL3D::IStereoDisplay *StereoDisplay = NULL; // Stereo display
NL3D::IStereoHMD *StereoHMD = NULL; // Head mount display
CSoundManager *SoundMngr = 0; // the sound manager
bool StereoDisplayAttached = false; // Is stereo display handling the display mode
CSoundManager *SoundMngr = NULL; // the sound manager
NL3D::UMaterial GenericMat; // Generic Material
NL3D::UTextContext *TextContext = 0; // Context for all the text in the client.
NL3D::UTextContext *TextContext = NULL; // Context for all the text in the client.
// Effects
NL3D::CFXAA *FXAA = NULL;
// Main 3D Objects
NL3D::UScene *Scene = 0;
NL3D::UScene *SceneRoot = 0;
NL3D::UInstanceGroup *BackgroundIG = 0;
NL3D::ULandscape *Landscape = 0;
NL3D::UCloudScape *CloudScape = 0;
NL3D::UScene *Scene = NULL;
NL3D::UScene *SceneRoot = NULL;
NL3D::UInstanceGroup *BackgroundIG = NULL;
NL3D::ULandscape *Landscape = NULL;
NL3D::UCloudScape *CloudScape = NULL;
NL3D::UCamera MainCam;
NL3D::UVisualCollisionManager *CollisionManager = 0;
NL3D::UVisualCollisionManager *CollisionManager = NULL;
#ifdef USE_WATER_ENV_MAP
CWaterEnvMapRdr WaterEnvMapRdr;
NL3D::UWaterEnvMap *WaterEnvMap = NULL;
@ -58,7 +62,7 @@ NLMISC::CMatrix InvMainSceneViewMatrix; // Matrix to transform from camera s
// Misc
bool InitCloudScape = true; // tells that the cloud scape must be reinitialized
CEntityAnimationManager *EAM = 0;
CEntityAnimationManager *EAM = NULL;
CProgress ProgressBar;
TBackground LoadingBackground = StartBackground;
string LoadingMusic;

View file

@ -42,6 +42,7 @@ namespace NL3D
class UWaterEnvMap;
class IStereoDisplay;
class IStereoHMD;
class CFXAA;
}
class CEntityAnimationManager;
@ -81,10 +82,14 @@ const float ExtraZoneLoadingVision = 100.f;
extern NL3D::UDriver *Driver; // The main 3D Driver
extern NL3D::IStereoDisplay *StereoDisplay; // Stereo display
extern NL3D::IStereoHMD *StereoHMD; // Head mount display
extern bool StereoDisplayAttached; // Is stereo display handling the display mode
extern CSoundManager *SoundMngr; // the sound manager
extern NL3D::UMaterial GenericMat; // Generic Material
extern NL3D::UTextContext *TextContext; // Context for all the text in the client.
// Effects
extern NL3D::CFXAA *FXAA;
// Main 3D Objects
extern NL3D::UScene *Scene;
extern NL3D::UScene *SceneRoot;

View file

@ -616,10 +616,16 @@ void initStereoDisplayDevice()
std::vector<NL3D::CStereoDeviceInfo> devices;
listStereoDisplayDevices(devices);
CStereoDeviceInfo *deviceInfo = NULL;
if (ClientCfg.VRDisplayDevice == std::string("Auto")
&& devices.begin() != devices.end())
if (ClientCfg.VRDisplayDevice == std::string("Auto"))
{
deviceInfo = &devices[0];
for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it)
{
if ((*it).AllowAuto)
{
deviceInfo = &(*it);
break;
}
}
}
else
{
@ -1069,34 +1075,6 @@ void prelogInit()
FPU_CHECKER_ONCE
// Test mouse & keyboard low-level mode, if DisableDirectInput not set.
// In case of failure, exit the client.
// In case of success, set it back to normal mode, to provide for the user
// the ability to manually set the firewall's permissions when the client connects.
// The low-level mode will actually be set when "launching" (after loading).
if (!ClientCfg.DisableDirectInput)
{
// Test mouse and set back to normal mode
if (!Driver->enableLowLevelMouse (true, ClientCfg.HardwareCursor))
{
ExitClientError (CI18N::get ("can_t_initialise_the_mouse").toUtf8 ().c_str ());
// ExitClientError() call exit() so the code after is never called
return;
}
Driver->enableLowLevelMouse (false, ClientCfg.HardwareCursor);
// Test keyboard and set back to normal mode
// NB : keyboard will be initialized later now
/*if (!Driver->enableLowLevelKeyboard (true))
{
ExitClientError (CI18N::get ("can_t_initialise_the_keyboard").toUtf8 ().c_str ());
// ExitClientError() call exit() so the code after is never called
return;
}
Driver->enableLowLevelKeyboard (false);
*/
}
// Set the monitor color properties
CMonitorColorProperties monitorColor;
for ( uint i=0; i<3; i++)
@ -1189,7 +1167,7 @@ void prelogInit()
CBloomEffect::getInstance().setDriver(Driver);
// init bloom effect
CBloomEffect::getInstance().init(driver != UDriver::Direct3d);
CBloomEffect::getInstance().init();
if (StereoDisplay) // VR_CONFIG
{

View file

@ -40,6 +40,8 @@
#include "nel/3d/u_cloud_scape.h"
#include "nel/3d/u_shape_bank.h"
#include "nel/3d/u_water_env_map.h"
#include "nel/3d/material.h"
#include "nel/3d/fxaa.h"
// Sound
#include "nel/sound/u_audio_mixer.h"
// Client
@ -125,6 +127,8 @@ namespace R2
extern bool ReloadUIFlag;
}
extern bool SetMousePosFirstTime;
extern EGSPD::CSeason::TSeason ManualSeasonValue;
UTextureFile *LoadingBitmap = NULL;
UTextureFile *LoadingBitmapFull = NULL;
@ -563,6 +567,9 @@ void initMainLoop()
if(Scene == 0)
nlerror("initMainLoop : Cannot create a Scene.");
// create effects
if (ClientCfg.FXAA && !FXAA) FXAA = new NL3D::CFXAA(Driver);
// use this scene for bloom effect
CBloomEffect::getInstance().setScene(Scene);
@ -1253,7 +1260,8 @@ void initMainLoop()
// NLMEMORY::CheckHeap (true);
// Re-initialise the mouse (will be now in hardware mode, if required)
InitMouseWithCursor (ClientCfg.HardwareCursor); // the return value of enableLowLevelMouse() has already been tested at startup
SetMousePosFirstTime = true;
InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached); // the return value of enableLowLevelMouse() has already been tested at startup
// Re-initialise the keyboard, now in low-level mode, if required
// NB nico : done at end of loading
@ -1496,6 +1504,7 @@ void initWelcomeWindow()
// ***************************************************************************
// NOTE: This feature is not really used anymore, it is a patch transition
void initHardwareCursor(bool secondCall)
{
CInterfaceManager * pIM = CInterfaceManager::getInstance();
@ -1571,6 +1580,7 @@ void initBloomConfigUI()
if(group)
group->setDefaultContextHelp(CI18N::get("uiFxTooltipBloom"));
ClientCfg.writeBool("FXAA", false);
ClientCfg.writeBool("Bloom", false);
ClientCfg.writeBool("SquareBloom", false);
ClientCfg.writeInt("DensityBloom", 0);

View file

@ -21,6 +21,7 @@
/////////////
#include "stdpch.h"
// Client
#include "global.h"
#include "actions.h"
#include "input.h"
#include "interface_v3/interface_manager.h"
@ -30,7 +31,6 @@
// 3D
#include "nel/3d/u_driver.h"
// Misc
#include "nel/misc/mouse_device.h"
#include "nel/misc/mouse_smoother.h"
#include "nel/misc/system_utils.h"
// Game Share
@ -54,7 +54,6 @@ extern CActionsManager Actions; // Actions Manager.
////////////
// GLOBAL //
////////////
IMouseDevice *MouseDevice = NULL;
bool MouseHardware = false;
bool MouseFreeLook = false;
float MouseCursorSpeed = 1.f;
@ -81,93 +80,40 @@ bool InitMouseWithCursor (bool hardware)
{
Driver->showCursor(false);
// First init ?
if (MouseDevice)
{
// No.. change soft to hard or hard to soft ?
if (hardware ^ MouseHardware)
{
// Ok, reinit the mouse
Driver->enableLowLevelMouse (false, false);
MouseDevice = NULL;
MouseHardware = false;
}
}
// Get the new mouse state
MouseHardware = hardware;
CViewPointer::setHWMouse( hardware );
// Reinit ?
if (MouseDevice == NULL)
// Update mouse information
UpdateMouse ();
if (InitMouseFirstTime)
{
if (!ClientCfg.DisableDirectInput)
InitMouseFirstTime = false;
}
else
{
if (!MouseFreeLook)
{
// mouse capture not taken in account for hardware mouse
MouseDevice = Driver->enableLowLevelMouse(true, hardware);
if (!MouseDevice)
return false;
}
// Update mouse information
UpdateMouse ();
if (InitMouseFirstTime)
{
InitMouseFirstTime = false;
}
else
{
if (!MouseFreeLook)
// Get the current mouse position
CInterfaceManager *pIm = CInterfaceManager::getInstance();
CViewPointer *vp = static_cast< CViewPointer* >( CWidgetManager::getInstance()->getPointer() );
Driver->showCursor(hardware);
if (vp)
{
// Get the current mouse position
if (hardware)
float x = (float) vp->getX();
float y = (float) vp->getY();
// First, hide the hardware mouse
uint width = Driver->getWindowWidth();
uint height = Driver->getWindowHeight();
if (SetMousePosFirstTime)
{
Driver->showCursor(true);
CViewPointer *pointer = static_cast< CViewPointer* >( CWidgetManager::getInstance()->getPointer() );
if (pointer)
{
float x = (float)pointer->getX()/(float)Driver->getWindowWidth();
float y = (float)pointer->getY()/(float)Driver->getWindowHeight();
if (SetMousePosFirstTime)
{
SetMousePosFirstTime = false;
}
else
{
Driver->setMousePos(x, y);
nlwarning("mouse pos %f,%f", x, y);
}
}
}
else
{
CInterfaceManager *pIm = CInterfaceManager::getInstance();
CViewPointer *vp = static_cast< CViewPointer* >( CWidgetManager::getInstance()->getPointer() );
Driver->showCursor(false);
SetMousePosFirstTime = false;
if (vp)
{
float x = (float) vp->getX();
float y = (float) vp->getY();
// First, hide the hardware mouse
if (MouseDevice)
{
MouseDevice->setMousePos(x, y);
}
else
{
uint width = Driver->getWindowWidth();
uint height = Driver->getWindowHeight();
if (width != 0 && height != 0)
{
Driver->setMousePos(x / width, y / height);
}
}
}
}
else if (width != 0 && height != 0)
{
nlwarning("mouse pos %u, %u", x, y);
Driver->setMousePos(x / width, y / height);
}
}
}
@ -187,45 +133,6 @@ bool IsMouseCursorHardware ()
// Set the mouse mode. Call this method once per frame to update window size
void UpdateMouse ()
{
// Freelook ?
if (MouseFreeLook)
{
// Raw mode
if (MouseDevice)
{
MouseDevice->setMessagesMode(IMouseDevice::RawMode);
MouseDevice->setMouseAcceleration(ClientCfg.FreeLookAcceleration);
}
else
{
// no mouse device implementation on X11 and Cocoa, emulate raw mode
Driver->emulateMouseRawMode(true);
}
}
else
{
// Set the mouse properties
if (MouseDevice)
{
// Get the driver size
uint32 width, height;
Driver->getWindowSize(width, height);
MouseDevice->setMessagesMode(IMouseDevice::NormalMode);
MouseDevice->setMouseMode(IMouseDevice::XAxis, IMouseDevice::Clamped);
MouseDevice->setMouseMode(IMouseDevice::YAxis, IMouseDevice::Clamped);
CRect window (0, 0, width, height);
MouseDevice->setMouseFrame(window);
MouseDevice->setFactors(1.f/std::max((float)width, 1.0f), 1.f/std::max((float)height, 1.0f));
MouseDevice->setMouseSpeed(MouseCursorSpeed);
MouseDevice->setMouseAcceleration(MouseCursorAcceleration);
}
else
{
// no mouse device implementation on X11 and Cocoa, emulate raw mode
Driver->emulateMouseRawMode(false);
}
}
if (!Driver->isSystemCursorCaptured())
{
DownMouseButtons = 0;
@ -303,19 +210,7 @@ void SetMouseCursor (bool updatePos)
if (updatePos)
{
if (MouseDevice)
{
MouseDevice->setMousePos((float)ix, (float)iy);
}
else
{
Driver->setMousePos(x, y);
}
if (MouseHardware)
{
Driver->setMousePos(x, y);
}
Driver->setMousePos(x, y);
}
// Update the interface pointer
@ -404,25 +299,18 @@ CNiceInputAuto::CNiceInputAuto()
{
if (_Count == 0)
{
Driver->enableLowLevelMouse(false, false); // but ignore direct input (win 32 msg only)
Driver->setCursor("curs_default.tga", CRGBA::White, 0, 0x15, 0x18);
Driver->showCursor(true); // keep cursor visible in windowed mode
MouseDevice = NULL;
Driver->enableLowLevelKeyboard (false);
}
++ _Count;
++_Count;
}
CNiceInputAuto::~CNiceInputAuto()
{
-- _Count;
--_Count;
nlassert(_Count >= 0);
if (_Count == 0)
{
InitMouseWithCursor (ClientCfg.HardwareCursor);
Driver->enableLowLevelKeyboard (!ClientCfg.DisableDirectInputKeyboard); // the return value has already been tested at startup
InitMouseWithCursor(ClientCfg.HardwareCursor && !StereoDisplayAttached);
}
}

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