/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2012 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ struct ObjStereo = [ PST_inst : PInstance, PST_iMode : I, PST_fSpacing : F, PST_bEnable : I, PST_iQuality : I, PST_fRatio : F, PST_iFrameAcc : I, PST_iNbFrame : I, PST_lostTick : I ]mkObjStereo;; var iRenderQuality_Default = 0;; var iRenderQuality_Auto = 1;; fun getStereoMode(mode)= if mode == 1 then SO3_SM_ANAGLYPH_YB else if mode == 2 then SO3_SM_INTERLACED_H else if mode == 3 then SO3_SM_INTERLACED_V else if mode == 4 then SO3_SM_INTERLACED_CB else if mode == 5 then SO3_SM_SIDE_BY_SIDE else if mode == 6 then SO3_SM_UP_DOWN else if mode == 7 then SO3_SM_QUAD_BUFFER else if mode == 8 then SO3_SM_OCULUS else if mode == 11 then SO3_SM_CARDBOARD else if mode == 12 then SO3_SM_MONO else SO3_SM_ANAGLYPH_RC;; fun getStereoModeByName(mode)= if !strcmp (strtrim mode) "Anaglyph red/cyan" then SO3_SM_ANAGLYPH_RC else if !strcmp (strtrim mode) "Anaglyph yellow/blue" then SO3_SM_ANAGLYPH_YB else if !strcmp (strtrim mode) "Horizontaly interlaced" then SO3_SM_INTERLACED_H else if !strcmp (strtrim mode) "Verticaly interlaced" then SO3_SM_INTERLACED_V else if !strcmp (strtrim mode) "Interlaced with checkerboard" then SO3_SM_INTERLACED_CB else if !strcmp (strtrim mode) "Side by side" then SO3_SM_SIDE_BY_SIDE else if !strcmp (strtrim mode) "Up/down" then SO3_SM_UP_DOWN else if !strcmp (strtrim mode) "Quad Buffer" then SO3_SM_QUAD_BUFFER else if !strcmp (strtrim mode) "Oculus" then SO3_SM_OCULUS else if !strcmp (strtrim mode) "Cardboard" then SO3_SM_CARDBOARD else if !strcmp (strtrim mode) "Mono" then SO3_SM_MONO else getStereoMode atoi mode;; fun deleteOb(inst)= let c3dXsession -> sessionstr in let V3DgetSessionView sessionstr -> viewstr in ( SO3BufferSetStereoMode sessionstr.V3D_sessionView.V3D_buffer SO3_SM_NONE; V3DsetVrMode viewstr 0; //force viewport size update V3DsetViewSizeDirty viewstr; ); 0;; fun cbScenePreRender(inst, sessionstr, etime, obstr)= let V3DgetSessionView sessionstr -> viewstr in // automatic quality switch if (obstr.PST_iNbFrame < 30) then ( set obstr.PST_iFrameAcc = obstr.PST_iFrameAcc + etime; set obstr.PST_iNbFrame = obstr.PST_iNbFrame + 1; ) else ( let 1000.0 /. (((itof obstr.PST_iFrameAcc) /. 1000.0) /. 60.0) -> fps in ( if (fps >=. 30.0) then ( set obstr.PST_lostTick = 0; ) else ( if (obstr.PST_lostTick != 0) then nil else set obstr.PST_lostTick = _tickcount; ); set obstr.PST_iFrameAcc = 0; set obstr.PST_iNbFrame = 0; if ((obstr.PST_lostTick == 0) || ((_tickcount - obstr.PST_lostTick) < 200)) then nil else ( if ((obstr.PST_fRatio <=. 0.75) || (obstr.PST_iQuality != iRenderQuality_Auto)) then nil else ( set obstr.PST_fRatio = obstr.PST_fRatio -. 0.25; set obstr.PST_lostTick = 0; let (V3DgetDefaultViewport (V3DgetSessionView c3dXsession)) -> viewportstr in let SO3ViewportGetPixelPositionSize viewportstr.V3D_viewport -> [_ _ lw lh] in let [ftoi ((itof lw) *. obstr.PST_fRatio) ftoi ((itof lh) *. obstr.PST_fRatio)] -> lsize in ( SO3BufferSetStereoMeshTextureSize viewstr.V3D_buffer lsize lsize; ); 0; ); ); ); ); 0;; fun cbEnable(inst, from, action, param, rep, obstr) = let V3DgetSessionView c3dXsession -> viewstr in ( SO3BufferSetStereoMode viewstr.V3D_buffer obstr.PST_iMode; SO3BufferSetStereoEyeSpacing viewstr.V3D_buffer obstr.PST_fSpacing; setPluginInstanceCbScenePreRender inst mkfun4 @cbScenePreRender obstr; set obstr.PST_bEnable = 1; V3DsetVrMode viewstr (if (obstr.PST_iMode == SO3_SM_MONO) then 0 else 1); //force viewport size update V3DsetViewSizeDirty viewstr; ); 0;; fun cbDisable(inst, from, action, param, rep, obstr) = let V3DgetSessionView c3dXsession -> viewstr in ( SO3BufferSetStereoMode viewstr.V3D_buffer SO3_SM_NONE; setPluginInstanceCbScenePreRender inst nil; set obstr.PST_bEnable = 0; V3DsetVrMode viewstr 0; //force viewport size update V3DsetViewSizeDirty viewstr; ); 0;; fun cbSetMode(inst, from, action, param, rep, obstr) = if param == nil then nil else let V3DgetSessionView c3dXsession -> viewstr in let getStereoModeByName param -> nmode in ( set obstr.PST_iMode = nmode; if !obstr.PST_bEnable then nil else ( let c3dXsession -> sessionstr in SO3BufferSetStereoMode sessionstr.V3D_sessionView.V3D_buffer obstr.PST_iMode; V3DsetVrMode viewstr (if (obstr.PST_iMode == SO3_SM_MONO) then 0 else 1); //force viewport size update V3DsetViewSizeDirty viewstr; ); ); 0;; fun cbSetEyesSpacing(inst, from, action, param, rep, obstr) = if (atof param) == nil then nil else ( set obstr.PST_fSpacing = (atof param); if !obstr.PST_bEnable then nil else let c3dXsession -> sessionstr in SO3BufferSetStereoEyeSpacing sessionstr.V3D_sessionView.V3D_buffer obstr.PST_fSpacing; ); 0;; fun newOb(inst)= let getStereoModeByName (getPluginInstanceParam inst "mode") -> mode in let atof (getPluginInstanceParam inst "eyespacing") -> eyespacing in let if eyespacing == nil then 0.065 else eyespacing -> eyespacing in let atoi (getPluginInstanceParam inst "init") -> init in let mkObjStereo [inst mode eyespacing init iRenderQuality_Auto 1.0 0 0 0] -> obstr in ( if !init then nil else cbEnable inst nil nil nil nil obstr; PluginRegisterAction inst "Enable" mkfun6 @cbEnable obstr; PluginRegisterAction inst "Disable" mkfun6 @cbDisable obstr; PluginRegisterAction inst "Set mode" mkfun6 @cbSetMode obstr; PluginRegisterAction inst "Set eyes spacing" mkfun6 @cbSetEyesSpacing obstr; ); setPluginInstanceCbDel inst @deleteOb; 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;