コード例 #1
0
ファイル: StDiagnostics.cpp プロジェクト: angelstudio/sview
bool StDiagnostics::open() {
    if(!StApplication::open()) {
        myMsgQueue->popAll();
        return false;
    }

    // initialize GL context
    myContext = myWindow->getContext();
    myContext->setMessagesQueue(myMsgQueue);
    if(!myContext->isGlGreaterEqual(2, 0)) {
        myMsgQueue->pushError(stCString("OpenGL 2.0 is required by StDiagnostics!"));
        myMsgQueue->popAll();
        return false;
    }
    myGUI->setContext(myContext);

    myWindow->setTargetFps(50.0);
    myWindow->setStereoOutput(true);

    if(!myGUI->stglInit()) {
        myMsgQueue->pushError(stCString("StDiagnostics - critical error:\nGUI initialization failed!"));
        myMsgQueue->popAll();
        myGUI.nullify();
        return false;
    }
    myGUI->stglResize(myWindow->stglViewport(ST_WIN_MASTER));
    registerHotKeys();
    return true;
}
コード例 #2
0
ファイル: StPlayList.cpp プロジェクト: KindDragon/sview
bool StPlayList::saveM3U(const StCString& thePath) {
    StRawFile aFile;
    if(thePath.isEmpty()
    || !aFile.openFile(StRawFile::WRITE, thePath)) {
        return false;
    }

    StMutexAuto anAutoLock(myMutex);
    aFile.write(stCString("#EXTM3U"));

    for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) {
        const StFileNode* aNode = anItem->getFileNode();
        if(aNode == NULL) {
            continue;
        } else if(aNode->size() < 2) {
            aFile.write(stCString("\n#EXTINF:0,"));
            if(anItem->hasCustomTitle()) {
                aFile.write(anItem->getTitle());
            }
            aFile.write(stCString("\n"));
            aFile.write(aNode->getPath());
        }
    }
    aFile.write(stCString("\n"));
    return true;
}
コード例 #3
0
ファイル: StDiagnostics.cpp プロジェクト: angelstudio/sview
StDiagnostics::StDiagnostics(const StHandle<StResourceManager>& theResMgr,
                             const StNativeWin_t                theParentWin,
                             const StHandle<StOpenInfo>&        theOpenInfo)
: StApplication(theResMgr, theParentWin, theOpenInfo) {
    myTitle = "sView - Stereoscopic Device Diagnostics";
    params.IsFullscreen = new StBoolParam(false);
    params.IsFullscreen->signals.onChanged.connect(this, &StDiagnostics::doFullscreen);

    myGUI = new StDiagnosticsGUI(this);

#if defined(__ANDROID__)
    addRenderer(new StOutInterlace  (myResMgr, theParentWin));
    addRenderer(new StOutAnaglyph   (myResMgr, theParentWin));
    addRenderer(new StOutDistorted  (myResMgr, theParentWin));
#else
    addRenderer(new StOutAnaglyph   (myResMgr, theParentWin));
    addRenderer(new StOutDual       (myResMgr, theParentWin));
    addRenderer(new StOutIZ3D       (myResMgr, theParentWin));
    addRenderer(new StOutInterlace  (myResMgr, theParentWin));
    addRenderer(new StOutDistorted  (myResMgr, theParentWin));
    addRenderer(new StOutPageFlipExt(myResMgr, theParentWin));
#endif

    // create actions
    StHandle<StAction> anAction;
    anAction = new StActionBool(stCString("DoFullscreen"), params.IsFullscreen);
    addAction(Action_Fullscreen, anAction, ST_VK_F, ST_VK_RETURN);

    anAction = new StActionIntSlot(stCString("DoStereoModeOn"),  stSlot(this, &StDiagnostics::doStereoMode), 1);
    addAction(Action_StereoModeOn,  anAction, ST_VK_S);

    anAction = new StActionIntSlot(stCString("DoStereoModeOff"), stSlot(this, &StDiagnostics::doStereoMode), 0);
    addAction(Action_StereoModeOff, anAction, ST_VK_M);
}
コード例 #4
0
ファイル: StActiveXCtrl.cpp プロジェクト: angelstudio/sview
int StActiveXCtrl::OnCreate(LPCREATESTRUCT theCreateStruct) {
    myBackBrush.CreateSolidBrush(RGB(0, 0, 0));
    if(COleControl::OnCreate(theCreateStruct) == -1) {
        return -1;
    }

    const StString ST_ASTERIX = '*';
    StMIME aMime(StString(myMimeType), ST_ASTERIX, ST_ASTERIX);
    myOpenInfo.setMIME(aMime);

    StArgumentsMap aDrawerArgs;
    const StString ST_SETTING_SRCFORMAT    = stCString("srcFormat");
    const StString ST_SETTING_COMPRESS     = stCString("toCompress");
    const StString ST_SETTING_ESCAPENOQUIT = stCString("escNoQuit");
    const StMIME ST_MIME_X_JPS("image/x-jps", ST_ASTERIX, ST_ASTERIX);
    const StMIME ST_MIME_JPS  ("image/jps",   ST_ASTERIX, ST_ASTERIX);
    const StMIME ST_MIME_X_PNS("image/x-pns", ST_ASTERIX, ST_ASTERIX);
    const StMIME ST_MIME_PNS  ("image/pns",   ST_ASTERIX, ST_ASTERIX);
    StArgument anArgSrcFormat = aDrawerArgs[ST_SETTING_SRCFORMAT];
    if(!anArgSrcFormat.isValid()) {
        anArgSrcFormat.setKey(ST_SETTING_SRCFORMAT);
        if(aMime == ST_MIME_X_JPS
        || aMime == ST_MIME_JPS
        || aMime == ST_MIME_X_PNS
        || aMime == ST_MIME_PNS) {
            anArgSrcFormat.setValue(st::formatToString(StFormat_SideBySide_RL));
            aDrawerArgs.add(anArgSrcFormat);
        }
    }
    aDrawerArgs.add(StArgument(ST_SETTING_COMPRESS,     "true")); // optimize memory usage
    aDrawerArgs.add(StArgument(ST_SETTING_ESCAPENOQUIT, "true")); // do not close plugin instance by Escape key
    myOpenInfo.setArgumentsMap(aDrawerArgs);

    // set window
    myParentWin = m_hWnd;

    // starts out plugin main loop in another thread
    myThread = new StThread(stThreadFunction, (void* )this, "StActiveXCtrl");

    // load URL
    StString aFilePath = loadURL(myHasPreview ? myUrlPreview : myUrlFull);
    if(aFilePath.isEmpty()) {
        if(!myHasPreview) {
            return 0;
        }
        if(myHasPreview) {
            // if we have 2 URLs - try to load another one
            aFilePath = loadURL(myUrlFull);
            if(aFilePath.isEmpty()) {
                return 0;
            }
            myHasPreview = false;
        }
    }

    myOpenInfo.setPath(aFilePath);
    myOpenEvent.set();
    return 0;
}
コード例 #5
0
ファイル: StTranslations.cpp プロジェクト: angelstudio/sview
StTranslations::StTranslations(const StHandle<StResourceManager>& theResMgr,
                               const StString&                    theModuleName)
: myResMgr(theResMgr),
  myModuleName(theModuleName),
  myWasReloaded(false) {
    params.language = new StEnumParam(0, stCString("language"), stCString("Language"));
    reload();
}
コード例 #6
0
ファイル: StBrowserPlugin.cpp プロジェクト: gkv311/sview
StBrowserPlugin::StBrowserPlugin(NSPluginCreateData* theCreateDataStruct)
    : nppInstance(theCreateDataStruct->instance),
      myResMgr(new StResourceManager()),
      myParentWin((StNativeWin_t )NULL),
#ifdef _WIN32
      myProcOrig(NULL),
      myBackBrush(CreateSolidBrush(RGB(0, 0, 0))),
#endif
      myToLoadFull(false),
      myIsActive(false),
      myToQuit(false) {
    if(ST_PLUGIN_INSTANCES.increment() == 1) {
        StSearchMonitors aMonitors;
        aMonitors.init(true); // force update of cached state
    }

    StArgumentsMap aDrawerArgs;
    for(int aParamId = 0; aParamId < theCreateDataStruct->argc; ++aParamId) {
        StString aParamName  = StString(theCreateDataStruct->argn[aParamId]);
        StString aParamValue = StString(theCreateDataStruct->argv[aParamId]);

        StArgument stArg(aParamName, aParamValue);
        aDrawerArgs.add(stArg);

        if(aParamName.isEqualsIgnoreCase(stCString("data-prv-url"))) {
            myPreviewUrl = aParamValue;
            myPreviewUrlUtf8.fromUrl(aParamValue);
        }
    }
    const StString ST_ASTERIX = '*';
    StMIME stMIME(StString(theCreateDataStruct->type), ST_ASTERIX, ST_ASTERIX);
    myOpenInfo.setMIME(stMIME);

    const StString ST_SETTING_SRCFORMAT    = stCString("srcFormat");
    const StString ST_SETTING_COMPRESS     = stCString("toCompress");
    const StString ST_SETTING_ESCAPENOQUIT = stCString("escNoQuit");
    const StMIME ST_MIME_X_JPS("image/x-jps", ST_ASTERIX, ST_ASTERIX);
    const StMIME ST_MIME_JPS  ("image/jps",   ST_ASTERIX, ST_ASTERIX);
    const StMIME ST_MIME_X_PNS("image/x-pns", ST_ASTERIX, ST_ASTERIX);
    const StMIME ST_MIME_PNS  ("image/pns",   ST_ASTERIX, ST_ASTERIX);
    StArgument anArgSrcFormat = aDrawerArgs[ST_SETTING_SRCFORMAT];
    if(!anArgSrcFormat.isValid()) {
        anArgSrcFormat.setKey(ST_SETTING_SRCFORMAT);
        if(stMIME == ST_MIME_X_JPS
                || stMIME == ST_MIME_JPS
                || stMIME == ST_MIME_X_PNS
                || stMIME == ST_MIME_PNS) {
            anArgSrcFormat.setValue(st::formatToString(StFormat_SideBySide_RL));
            aDrawerArgs.add(anArgSrcFormat);
        }
    }
    aDrawerArgs.add(StArgument(ST_SETTING_COMPRESS,     "true")); // optimize memory usage
    aDrawerArgs.add(StArgument(ST_SETTING_ESCAPENOQUIT, "true")); // do not close plugin instance by Escape key
    myOpenInfo.setArgumentsMap(aDrawerArgs);
}
コード例 #7
0
ファイル: StOutIZ3D.cpp プロジェクト: angelstudio/sview
StOutIZ3D::StOutIZ3D(const StHandle<StResourceManager>& theResMgr,
                     const StNativeWin_t                theParentWindow)
: StWindow(theResMgr, theParentWindow),
  mySettings(new StSettings(theResMgr, ST_OUT_PLUGIN_NAME)),
  myFrBuffer(new StGLStereoFrameBuffer()),
  myToCompressMem(myInstancesNb.increment() > 1),
  myIsBroken(false) {
    const StSearchMonitors& aMonitors = StWindow::getMonitors();

    // detect connected displays
    int aSupportLevel = ST_DEVICE_SUPPORT_NONE;
    for(size_t aMonIter = 0; aMonIter < aMonitors.size(); ++aMonIter) {
        const StMonitor& aMon = aMonitors[aMonIter];
        if(isFrontDisplay(aMon.getPnPId())
        || isBackDisplay (aMon.getPnPId())) {
            aSupportLevel = ST_DEVICE_SUPPORT_PREFER; // we sure that iZ3D connected
            break;
        }/* else if(aMon.getPnPId() == IZ3D_MODEL_MATROXTH2GO0
               || aMon.getPnPId() == IZ3D_MODEL_MATROXTH2GO1) {
            aSupportLevel = ST_DEVICE_SUPPORT_FULL; // is it possible
        }*/
    }

    // devices list
    StHandle<StOutDevice> aDevice = new StOutDevice();
    aDevice->PluginId = ST_OUT_PLUGIN_NAME;
    aDevice->DeviceId = stCString("iZ3D");
    aDevice->Priority = aSupportLevel;
    aDevice->Name     = stCString("IZ3D Display");
    myDevices.add(aDevice);

    // shader switch option
    params.Glasses = new StEnumParam(myShaders.getMode(), stCString("tableId"), stCString("tableId"));
    params.Glasses->signals.onChanged.connect(&myShaders, &StOutIZ3DShaders::doSetMode);

    // load window position
    if(isMovable()) {
        StRect<int32_t> aRect;
        if(!mySettings->loadInt32Rect(ST_SETTING_WINDOWPOS, aRect)) {
            aRect = defaultRect();
        }
        StWindow::setPlacement(aRect, true);
    }
    updateStrings();
    StWindow::setTitle("sView - iZ3D Renderer");

    // load parameters
    mySettings->loadParam(params.Glasses);

    // request slave window
    StWindow::setAttribute(StWinAttr_SlaveCfg, StWinSlave_slaveSync);
}
コード例 #8
0
ファイル: StJpegParser.cpp プロジェクト: KindDragon/sview
bool StJpegParser::setupJps(const StFormatEnum theFormat) {
    if(myBuffer == NULL) {
        return false;
    }

    if(myOffsets[Offset_Jps] == 0) {
        if(myOffsets[Offset_Dqt] == 0) {
            return false;
        }

        // insert section right after DQT
        const StCString THE_APP_DESC = stCString("Written by sView");
        const uint16_t  aDqtLen  = StAlienData::Get16uBE(myBuffer + myOffsets[Offset_Dqt] + 2);
        const ptrdiff_t anOffset = myOffsets[Offset_Dqt] + aDqtLen + 2;
        const uint16_t  aJpsLen  = 16 + 2 + ((uint16_t )THE_APP_DESC.Size + 1);
        if(!insertSection(M_APP3, aJpsLen, anOffset)) {
            return false;
        }

        myOffsets[Offset_Jps] = anOffset;
        stUByte_t* aData = myBuffer + anOffset + 2;
        stMemCpy(aData + 2, "_JPSJPS_", 8);
        StAlienData::Set16uBE(aData + 10, 4);
        StAlienData::Set32uBE(aData + 12, 0);
        StAlienData::Set16uBE(aData + 16, (uint16_t )THE_APP_DESC.Size);
        stMemCpy(aData + 18, THE_APP_DESC.String, THE_APP_DESC.Size + 1);
    } else if(myStFormat == theFormat) {
        return false;
    }

    myStFormat = theFormat;
    uint32_t aStereoDesc = 0x00000001;
    switch(theFormat) {
        case ST_V_SRC_PARALLEL_PAIR:
            aStereoDesc |= SD_LAYOUT_SIDEBYSIDE | SD_LEFT_FIELD_FIRST;
            break;
        case ST_V_SRC_SIDE_BY_SIDE:
            aStereoDesc |= SD_LAYOUT_SIDEBYSIDE;
            break;
        case ST_V_SRC_OVER_UNDER_LR:
            aStereoDesc |= SD_LAYOUT_OVERUNDER | SD_LEFT_FIELD_FIRST;
            break;
        case ST_V_SRC_OVER_UNDER_RL:
            aStereoDesc |= SD_LAYOUT_OVERUNDER;
            break;
        case ST_V_SRC_ROW_INTERLACE:
            aStereoDesc |= SD_LAYOUT_INTERLEAVED;
            break;
        case ST_V_SRC_ANAGLYPH_RED_CYAN:
            aStereoDesc |= SD_LAYOUT_ANAGLYPH;
            break;
        case ST_V_SRC_MONO:
        default:
            aStereoDesc = 0x00000000;
            break;
    }

    StAlienData::Set32uBE(myBuffer + myOffsets[Offset_Jps] + 2 + 8 + 2 + 2, aStereoDesc);
    return true;
}
コード例 #9
0
ファイル: StOutAnaglyph.cpp プロジェクト: KindDragon/sview
bool StOutAnaglyph::create() {
    StWindow::show();
    if(!StWindow::create()) {
        return false;
    }

    // initialize GL context
    myContext = StWindow::getContext();
    myContext->setMessagesQueue(myMsgQueue);
    if(!myContext->isGlGreaterEqual(2, 0)) {
        myMsgQueue->pushError(stCString("OpenGL 2.0 is required by Anaglyph Output"));
        myIsBroken = true;
        return true;
    }

    myContext->stglSetVSync((StGLContext::VSync_Mode )StWindow::params.VSyncMode->getValue());
    StWindow::params.VSyncMode->signals.onChanged += stSlot(this, &StOutAnaglyph::doSwitchVSync);

    // INIT shaders
    const StString aShadersRoot = StProcess::getStShareFolder() + "shaders" + SYS_FS_SPLITTER
                                + ST_OUT_PLUGIN_NAME + SYS_FS_SPLITTER;
    StGLVertexShader aVertShader("Anaglyph"); // common vertex shader
    if(!aVertShader.initFile(*myContext, aShadersRoot + VSHADER)
    || !initProgram(*myContext, mySimpleAnaglyph, aVertShader,
                    aShadersRoot + FSHADER_SIMPLE)
    || !initProgram(*myContext, myGrayAnaglyph, aVertShader,
                    aShadersRoot + FSHADER_GRAY)
    || !initProgram(*myContext, myTrueAnaglyph, aVertShader,
                    aShadersRoot + FSHADER_TRUE)
    || !initProgram(*myContext, myOptimAnaglyph, aVertShader,
                    aShadersRoot + FSHADER_OPTIM)
    || !initProgram(*myContext, myYellowAnaglyph, aVertShader,
                    aShadersRoot + FSHADER_YELLOW)
    || !initProgram(*myContext, myYellowDubiosAnaglyph, aVertShader,
                    aShadersRoot + FSHADER_YELLOWD)
    || !initProgram(*myContext, myGreenAnaglyph, aVertShader,
                    aShadersRoot + FSHADER_GREEN)) {
        aVertShader.release(*myContext);
        myMsgQueue->pushError(stCString("Anaglyph output - critical error:\nShaders initialization failed!"));
        myIsBroken = true;
        return true;
    }

    aVertShader.release(*myContext);
    myIsBroken = false;
    return true;
}
コード例 #10
0
ファイル: StPlayList.cpp プロジェクト: KindDragon/sview
void StPlayList::setExtensions(const StArrayList<StString>& theExtensions) {
    myExtensions = theExtensions;
    for(size_t anExtId = 0; anExtId < myExtensions.size(); ++anExtId) {
        if(myExtensions[anExtId].isEqualsIgnoreCase(stCString("m3u"))) {
            myExtensions.remove(anExtId); // playlist files are treated in special way
            --anExtId;
        }
    }
}
コード例 #11
0
StGLRangeFieldFloat32::StGLRangeFieldFloat32(StGLWidget* theParent,
                                             const StHandle<StFloat32Param>& theTrackedValue,
                                             const int theLeft, const int theTop,
                                             const StGLCorner theCorner)
: StGLWidget(theParent, theLeft, theTop, theCorner),
  myTrackValue(theTrackedValue),
  myValueText(NULL),
  myFormat(stCString("%+01.3f")) {
    myTrackValue->signals.onChanged   += stSlot(this, &StGLRangeFieldFloat32::onValueChange);
    StGLWidget::signals.onMouseUnclick = stSlot(this, &StGLRangeFieldFloat32::doMouseUnclick);
}
コード例 #12
0
ファイル: StImageFile.cpp プロジェクト: angelstudio/sview
StImageFile::ImageClass StImageFile::imgLibFromString(const StString& thePreferred) {
    StImageFile::ImageClass aPreferred = ST_LIBAV;
    if(thePreferred.isEqualsIgnoreCase(stCString("LibAV")) ||
       thePreferred.isEqualsIgnoreCase(stCString("FFmpeg")) ||
       thePreferred.isEqualsIgnoreCase(stCString("StAVImage"))) {
        aPreferred = ST_LIBAV;
    } else if(thePreferred.isEqualsIgnoreCase(stCString("FreeImage")) ||
              thePreferred.isEqualsIgnoreCase(stCString("StFreeImage"))) {
        aPreferred = ST_FREEIMAGE;
    } else if(thePreferred.isEqualsIgnoreCase(stCString("DevIL")) ||
              thePreferred.isEqualsIgnoreCase(stCString("StDevILImage"))) {
        aPreferred = ST_DEVIL;
    } else if(thePreferred.isEqualsIgnoreCase(stCString("WebP")) ||
              thePreferred.isEqualsIgnoreCase(stCString("StWebPImage"))) {
        aPreferred = ST_WEBP;
    }
    return aPreferred;
}
コード例 #13
0
ファイル: StWindow.cpp プロジェクト: angelstudio/sview
void StWindow::copySignals() {
    params.VSyncMode = new StEnumParam(0, stCString("vsyncMode"), stCString("VSync mode"));
    params.VSyncMode->changeValues().add("Off");
    params.VSyncMode->changeValues().add("On");
    params.VSyncMode->changeValues().add("Mixed");

    myWin->signals.onClose     = &signals.onClose;
    myWin->signals.onPause     = &signals.onPause;
    myWin->signals.onResize    = &signals.onResize;
    myWin->signals.onAnotherMonitor = &signals.onAnotherMonitor;
    myWin->signals.onKeyUp     = &signals.onKeyUp;
    myWin->signals.onKeyDown   = &signals.onKeyDown;
    myWin->signals.onKeyHold   = &signals.onKeyHold;
    myWin->signals.onMouseUp   = &signals.onMouseUp;
    myWin->signals.onMouseDown = &signals.onMouseDown;
    myWin->signals.onTouch     = &signals.onTouch;
    myWin->signals.onGesture   = &signals.onGesture;
    myWin->signals.onScroll    = &signals.onScroll;
    myWin->signals.onFileDrop  = &signals.onFileDrop;
    myWin->signals.onNavigate  = &signals.onNavigate;
    myWin->signals.onAction    = &signals.onAction;
}
コード例 #14
0
ファイル: StOutAnaglyph.cpp プロジェクト: KindDragon/sview
void StOutAnaglyph::stglDraw() {
    myFPSControl.setTargetFPS(StWindow::getTargetFps());
    const StGLBoxPx aVPort = StWindow::stglViewport(ST_WIN_MASTER);
    if(!StWindow::isStereoOutput() || myIsBroken) {
        StWindow::stglMakeCurrent(ST_WIN_MASTER);
        myContext->stglResizeViewport(aVPort);
        if(myToCompressMem) {
            myFrBuffer->release(*myContext);
        }

        StWindow::signals.onRedraw(ST_DRAW_LEFT);

        myFPSControl.sleepToTarget(); // decrease FPS to target by thread sleeps
        StWindow::stglSwap(ST_WIN_MASTER);
        ++myFPSControl;
        return;
    }
    StWindow::stglMakeCurrent(ST_WIN_MASTER);

    // resize FBO
    if(!myFrBuffer->initLazy(*myContext, aVPort.width(), aVPort.height(), StWindow::hasDepthBuffer())) {
        myMsgQueue->pushError(stCString("Anaglyph output - critical error:\nFrame Buffer Object resize failed!"));
        myIsBroken = true;
        return;
    }

    // draw into virtual frame buffers (textures)
    myFrBuffer->setupViewPort(*myContext);       // we set TEXTURE sizes here
    myFrBuffer->bindBufferLeft(*myContext);
        StWindow::signals.onRedraw(ST_DRAW_LEFT);
    myFrBuffer->bindBufferRight(*myContext);
        StWindow::signals.onRedraw(ST_DRAW_RIGHT);
    myFrBuffer->unbindBufferRight(*myContext);

    // now draw to real screen buffer
    // clear the screen and the depth buffer
    myContext->stglResizeViewport(aVPort);
    myContext->core20fwd->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    myContext->core20fwd->glDisable(GL_DEPTH_TEST);
    myContext->core20fwd->glDisable(GL_BLEND);
    myFrBuffer->bindMultiTexture(*myContext);
    myFrBuffer->drawQuad(*myContext, myStereoProgram);
    myFrBuffer->unbindMultiTexture(*myContext);

    myFPSControl.sleepToTarget(); // decrease FPS to target by thread sleeps
    StWindow::stglSwap(ST_WIN_MASTER);
    ++myFPSControl;
}
コード例 #15
0
StOutPageFlipExt::StOutPageFlipExt(const StHandle<StResourceManager>& theResMgr,
                                   const StNativeWin_t                theParentWindow)
: StOutPageFlip(theResMgr, theParentWindow),
  myVpSizeY(0),
  myVpSizeX(0),
  myIsQuiting(false) {
    myWinRect.left()   = 0;
    myWinRect.right()  = 0;
    myWinRect.top()    = 0;
    myWinRect.bottom() = 0;

    // Control Code option
    params.ControlCode = new StEnumParam(DEVICE_CONTROL_NONE, stCString("deviceControl"), stCString("deviceControl"));
    params.ControlCode->defineOption(DEVICE_CONTROL_NONE,      stCString("noCodes"));
    params.ControlCode->defineOption(DEVICE_CONTROL_BLUELINE,  stCString("blueLine"));
    params.ControlCode->defineOption(DEVICE_CONTROL_WHITELINE, stCString("whiteLine"));
    params.ControlCode->defineOption(DEVICE_CONTROL_ED_ON_OFF, stCString("eD"));
    params.ControlCode->signals.onChanged.connect(this, &StOutPageFlipExt::doSetDeviceControl);

    // load shutter glasses controller
    updateStringsExt();
    mySettings->loadParam(params.ControlCode);
    myToResetDevice = false;
}
コード例 #16
0
ファイル: StPlayList.cpp プロジェクト: KindDragon/sview
bool StPlayList::checkExtension(const StString& thePath) {
    if(StFolder::isFolder(thePath)) {
        // just folder
        return true;
    }
    StString anExtension = StFileNode::getExtension(thePath);
    for(size_t anExtId = 0; anExtId < myExtensions.size(); ++anExtId) {
        if(anExtension.isEqualsIgnoreCase(myExtensions[anExtId])) {
            return true;
        }
    }
    if(anExtension.isEqualsIgnoreCase(stCString("m3u"))) {
        return true;
    }
    return false;
}
コード例 #17
0
ファイル: StTranslations.cpp プロジェクト: angelstudio/sview
void StTranslations::updateLangCode(const int32_t theNewLang) {
    const StString& aLang = params.language->getValues()[theNewLang];
    if(aLang == stCString("русский")) {
        myLangCode = "rus";
    } else if(aLang == stCString("français")) {
        myLangCode = "fre";
        //myLangCode = "fra";
    } else if(aLang == stCString("Deutsch")) {
        myLangCode = "ger";
        //myLangCode = "deu";
    } else if(aLang == stCString("한국어")) {
        myLangCode = "kor";
    } else if(aLang == stCString("简体中文")) {
        myLangCode = "chi";
    } else if(aLang == stCString("Čeština")) {
        myLangCode = "cze";
    } else if(aLang == stCString("English")) {
        myLangCode = "eng";
    } else {
        myLangCode.clear();
    }
}
コード例 #18
0
ファイル: StFormatEnum.cpp プロジェクト: KindDragon/sview
StFormatEnum st::formatFromName(const StString& theFileName,
                                bool&           theIsAnamorph) {
    StString aName, anExt;
    StFileNode::getNameAndExtension(theFileName, aName, anExt);
    aName.toLowerCase();
    anExt.toLowerCase();
    if(anExt == stCString("pns")
    || anExt == stCString("jps")) {
        theIsAnamorph = false;
        return ST_V_SRC_SIDE_BY_SIDE;
    }

    // this is not optimized search, but should be OK for most use cases
    if(aName.isContains(stCString("halfou"))
    || aName.isContains(stCString("half-ou"))
    || aName.isContains(stCString("half_ou"))
    || aName.isContains(stCString("half.ou"))
    || aName.isContains(stCString("half ou"))
    || aName.isEndsWith(stCString("-hou"))
    || aName.isEndsWith(stCString("_hou"))
    || aName.isEndsWith(stCString(".hou"))
    || aName.isEndsWith(stCString(" hou"))
    || aName.isEndsWith(stCString("-abq"))) {
        theIsAnamorph = true;
        return ST_V_SRC_OVER_UNDER_LR;
    } else if(aName.isEndsWith(stCString("-baq"))) {
        theIsAnamorph = true;
        return ST_V_SRC_OVER_UNDER_RL;
    } else if(aName.isEndsWith(stCString("-ab"))
           //|| aName.isContains(stCString("-ou")) // too ambiguous
           //|| aName.isContains(stCString("_ou"))
           //|| aName.isContains(stCString(".ou"))
           //|| aName.isContains(stCString(" ou"))
             ) {
        theIsAnamorph = false;
        return ST_V_SRC_OVER_UNDER_LR;
    } else if(aName.isEndsWith(stCString("-ba"))) {
        theIsAnamorph = false;
        return ST_V_SRC_OVER_UNDER_RL;
    } else if(aName.isContains(stCString("halfsbs"))
           || aName.isContains(stCString("half-sbs"))
           || aName.isContains(stCString("half_sbs"))
           || aName.isContains(stCString("half.sbs"))
           || aName.isContains(stCString("half sbs"))
           || aName.isContains(stCString(".hsbs"))
           || aName.isContains(stCString("-hsbs"))
           || aName.isContains(stCString("_hsbs"))
           || aName.isContains(stCString(" hsbs"))
           || aName.isEndsWith(stCString("-lrq"))) {
        theIsAnamorph = true;
        return ST_V_SRC_PARALLEL_PAIR;
    } else if(aName.isEndsWith(stCString("-rlq"))) {
        theIsAnamorph = true;
        return ST_V_SRC_SIDE_BY_SIDE;
    } else if(aName.isContains(stCString("-sbs"))
           || aName.isContains(stCString(".sbs"))
           || aName.isContains(stCString(" sbs"))
           || aName.isEndsWith(stCString("-lr"))) {
        theIsAnamorph = false;
        return ST_V_SRC_PARALLEL_PAIR;
    } else if(aName.isEndsWith(stCString("-rl"))) {
        theIsAnamorph = false;
        return ST_V_SRC_SIDE_BY_SIDE;
    } else if(aName.isEndsWith(stCString("-2d"))) {
        theIsAnamorph = false;
        return ST_V_SRC_MONO;
    }
    theIsAnamorph = false;
    return ST_V_SRC_AUTODETECT;
}
コード例 #19
0
ファイル: StFolder.cpp プロジェクト: KindDragon/sview
StFolder::StFolder()
: StFileNode(stCString(""), NULL, NODE_TYPE_FOLDER) {
    //
}
コード例 #20
0
ファイル: StFileNode.cpp プロジェクト: angelstudio/sview
StFileNode::StFileNode()
: StNode(stCString(""), NULL, NODE_TYPE_FILE) {
    //
}
コード例 #21
0
ファイル: StImageFile.cpp プロジェクト: angelstudio/sview
StImageFile::ImageType StImageFile::guessImageType(const StString& theFileName,
                                                   const StMIME&   theMIMEType) {
    StString anExt = !theMIMEType.isEmpty() ? theMIMEType.getExtension() : StFileNode::getExtension(theFileName);
    if(anExt.isEqualsIgnoreCase(stCString("mpo"))
    || theMIMEType.getMIMEType().isEquals(stCString("image/mpo"))
    || theMIMEType.getMIMEType().isEquals(stCString("image/x-mpo"))) {
        return StImageFile::ST_TYPE_MPO;
    } else if(anExt.isEqualsIgnoreCase(stCString("jps"))
           || theMIMEType.getMIMEType().isEquals(stCString("image/jps"))
           || theMIMEType.getMIMEType().isEquals(stCString("image/x-jps"))) {
        return StImageFile::ST_TYPE_JPS;
    } else if(anExt.isEqualsIgnoreCase(stCString("pns"))
           || theMIMEType.getMIMEType().isEquals(stCString("image/pns"))
           || theMIMEType.getMIMEType().isEquals(stCString("image/x-pns"))) {
        return StImageFile::ST_TYPE_PNS;
    } else if(anExt.isEqualsIgnoreCase(stCString("jpg"))
           || anExt.isEqualsIgnoreCase(stCString("jpeg"))
           || anExt.isEqualsIgnoreCase(stCString("jpe"))
           || theMIMEType.getMIMEType().isEquals(stCString("image/jpg"))
           || theMIMEType.getMIMEType().isEquals(stCString("image/jpeg"))) {
        return StImageFile::ST_TYPE_JPEG;
    } else if(anExt.isEqualsIgnoreCase(stCString("png"))
           || theMIMEType.getMIMEType().isEquals(stCString("image/png"))) {
        return StImageFile::ST_TYPE_PNG;
    } else if(anExt.isEqualsIgnoreCase(stCString("exr"))) {
        return StImageFile::ST_TYPE_EXR;
    } else if(anExt.isEqualsIgnoreCase(stCString("psd"))) {
        return StImageFile::ST_TYPE_PSD;
    } else if(anExt.isEqualsIgnoreCase(stCString("ico"))) {
        return StImageFile::ST_TYPE_ICO;
    } else if(anExt.isEqualsIgnoreCase(stCString("hdr"))) {
        return StImageFile::ST_TYPE_HDR;
    } else if(anExt.isEqualsIgnoreCase(stCString("webp"))
           || theMIMEType.getMIMEType().isEquals(stCString("image/webp"))) {
        return StImageFile::ST_TYPE_WEBP;
    } else if(anExt.isEqualsIgnoreCase(stCString("webpll"))
           || theMIMEType.getMIMEType().isEquals(stCString("image/webpll"))) {
        return StImageFile::ST_TYPE_WEBPLL;
    }
    return StImageFile::ST_TYPE_NONE;
}
コード例 #22
0
ファイル: StTranslations.cpp プロジェクト: angelstudio/sview
void StTranslations::reload() {
    params.language->changeValues().clear();

    // detect available translations
    StArrayList<StString> aFolders;
    myResMgr->listSubFolders("lang", aFolders);
    for(size_t aNodeId = 0; aNodeId < aFolders.size(); ++aNodeId) {
        myLangFolderList.add(aFolders[aNodeId]);

        const StString aNameFile = StString("lang" ST_FILE_SPLITTER) + aFolders[aNodeId] + ST_FILE_SPLITTER "language.lng";
        StHandle<StResource> aRes = myResMgr->getResource(aNameFile);
        StString aName;
        if(!aRes.isNull()
        &&  aRes->read()) {
            const char*  aSrc = (const char* )aRes->getData();
            const size_t aLen = (size_t      )aRes->getSize();
            aName = StString(aSrc, aLen);
        }
        params.language->changeValues().add(aName.isEmpty() ? aFolders[aNodeId] : aName);
    }
#if defined(__ANDROID__)
    if(params.language->getValues().isEmpty()) {
        // no way to list sub-folder on Android - check known translations
        if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "English" ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) {
            params.language->changeValues().add("English");
            myLangFolderList.add("English");
        }
        if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "Russian" ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) {
            params.language->changeValues().add("русский");
            myLangFolderList.add("Russian");
        }
        if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "French" ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) {
            params.language->changeValues().add("français");
            myLangFolderList.add("French");
        }
        if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "German" ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) {
            params.language->changeValues().add("Deutsch");
            myLangFolderList.add("German");
        }
        if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "Korean" ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) {
            params.language->changeValues().add("한국어");
            myLangFolderList.add("Korean");
        }
        if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "ChineseS" ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) {
            params.language->changeValues().add("简体中文");
            myLangFolderList.add("ChineseS");
        }
        if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "Czech"  ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) {
            params.language->changeValues().add("Čeština");
            myLangFolderList.add("Czech");
        }
    }
#endif

    if(params.language->getValues().isEmpty()) {
        // add built-in language
        params.language->changeValues().add("English");
        myLangFolderList.add("English");
    }

    size_t     anIdInList = 0;
    StString   aLangParam("English");
    StSettings aGlobalSettings(myResMgr, ST_GLOBAL_SETTINGS_GROUP);
    bool isLangSet = false;
    if(!aGlobalSettings.loadString(ST_SETTING_LANGUAGE, aLangParam)) {
        // try to use system-wide language settings
        const StString& aLang = myResMgr->getSystemLanguage();
        if(aLang.isEqualsIgnoreCase(stCString("ru"))) {
            if(myLangFolderList.contains(stCString("Russian"),  anIdInList)
            || myLangFolderList.contains(stCString("русский"),  anIdInList)) {
                params.language->setValue(int32_t(anIdInList));
                isLangSet = true;
            }
        } else if(aLang.isEqualsIgnoreCase(stCString("de"))) {
            if(myLangFolderList.contains(stCString("German"),   anIdInList)
            || myLangFolderList.contains(stCString("Deutsch"),  anIdInList)) {
                params.language->setValue(int32_t(anIdInList));
                isLangSet = true;
            }
        } else if(aLang.isEqualsIgnoreCase(stCString("fr"))) {
            if(myLangFolderList.contains(stCString("French"),   anIdInList)
            || myLangFolderList.contains(stCString("français"), anIdInList)) {
                params.language->setValue(int32_t(anIdInList));
                isLangSet = true;
            }
        } else if(aLang.isEqualsIgnoreCase(stCString("ko"))) {
            if(myLangFolderList.contains(stCString("Korean"),   anIdInList)) {
                params.language->setValue(int32_t(anIdInList));
                isLangSet = true;
            }
        } else if(aLang.isEqualsIgnoreCase(stCString("zh"))) {
            if(myLangFolderList.contains(stCString("ChineseS"), anIdInList)) {
                params.language->setValue(int32_t(anIdInList));
                isLangSet = true;
            }
        } else if(aLang.isEqualsIgnoreCase(stCString("cs"))) {
            if(myLangFolderList.contains(stCString("Čeština"), anIdInList)) {
                params.language->setValue(int32_t(anIdInList));
                isLangSet = true;
            }
        }
    }
    if(!isLangSet) {
        if(myLangFolderList.contains(aLangParam,           anIdInList)
        || myLangFolderList.contains(stCString("English"), anIdInList)) {
            params.language->setValue(int32_t(anIdInList));
        }
    }
    updateLangCode(int32_t(anIdInList));

    const StString& aFolderName = myLangFolderList[anIdInList];
    const StString  aResName    = StString()
                                + "lang"       + SYS_FS_SPLITTER
                                + aFolderName  + SYS_FS_SPLITTER
                                + myModuleName + StTranslations::DEFAULT_SUFFIX;
    StHandle<StResource> aRes = myResMgr->getResource(aResName);
    if(!aRes.isNull()
    &&  aRes->read()) {
        const char* aSrc = (const char* )aRes->getData();
        const int   aLen = aRes->getSize();
        read(aSrc, aLen);
    }

    // connect signal
    params.language->signals.onChanged.connect(this, &StTranslations::setLanguage);
}
コード例 #23
0
ファイル: StPlayList.cpp プロジェクト: KindDragon/sview
void StPlayList::open(const StCString& thePath,
                      const StCString& theItem) {
    StMutexAuto anAutoLock(myMutex);

    // check if it is recently played playlist
    bool hasTarget = !theItem.isEmpty();
    StString aTarget = hasTarget ? theItem : thePath;
    if(!hasTarget) {
        for(size_t anIter = 0; anIter < myRecent.size(); ++anIter) {
            const StHandle<StRecentItem>& aRecent = myRecent[anIter];
            const StHandle<StFileNode>&   aFile   = aRecent->File;
            if(aFile->size() != 1) {
                continue;
            }

            if(thePath.isEquals(aFile->getPath())) {
                hasTarget = true;
                aTarget = aFile->getValue(0)->getSubPath();
                break;
            }
        }
    }

    clear();
    int aSearchDeep = myRecursionDeep;
    StString aFolderPath;
    StString aFileName;
    if(StFolder::isFolder(thePath)) {
        // add all files from the folder and subfolders
        aFolderPath = thePath;
        aSearchDeep = myRecursionDeep;
        myPlsFile   = addRecentFile(StFileNode(thePath)); // append to recent files list
    } else if(StFileNode::isFileExists(thePath)) {
        // search only current folder
        StFileNode::getFolderAndFile(thePath, aFolderPath, aFileName);
        aSearchDeep = 1;
        bool hasSupportedExt = false;
        StString anExt = StFileNode::getExtension(aFileName);
        for(size_t anExtId = 0; anExtId < myExtensions.size() && !hasSupportedExt; ++anExtId) {
            hasSupportedExt = anExt.isEqualsIgnoreCase(myExtensions[anExtId]);
        }

        // parse m3u playlist
        if(anExt.isEqualsIgnoreCase(stCString("m3u"))) {
            StRawFile aRawFile(thePath);
            if(aRawFile.readFile()) {
                StString aTitle;
                char* anIter = (char* )aRawFile.getBuffer();
                if(anIter[0] == '\xEF' && anIter[1] == '\xBB' && anIter[2] == '\xBF') {
                    // skip BOM for UTF8 written by some stupid programs
                    anIter += 3;
                }
                while(anIter != NULL) {
                    anIter = parseM3UIter(anIter, aTitle);
                }

                myPlsFile = addRecentFile(StFileNode(thePath)); // append to recent files list
                if(hasTarget) {
                    // set current item
                    for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) {
                        if(anItem->getPath() == aTarget) {
                            myCurrent = anItem;
                            break;
                        }
                    }
                }

                anAutoLock.unlock();
                signals.onPlaylistChange();
                return;
            }
        }

        if(!hasSupportedExt) {
            // file with unsupported extension?
            StFileNode* aFileNode = new StFileNode(thePath, &myFoldersRoot);
            myFoldersRoot.add(aFileNode);
            addPlayItem(new StPlayItem(aFileNode, myDefStParams));
        }
    } else {
        // not a filesystem element - probably url or invalid path
        StFileNode* aFileNode = new StFileNode(thePath, &myFoldersRoot);
        myFoldersRoot.add(aFileNode);
        addRecentFile(*aFileNode); // append to recent files list
        addPlayItem(new StPlayItem(aFileNode, myDefStParams));

        anAutoLock.unlock();
        signals.onPlaylistChange();
        return;
    }
    StFolder* aSubFolder = new StFolder(aFolderPath, &myFoldersRoot);
    aSubFolder->init(myExtensions, aSearchDeep);
    myFoldersRoot.add(aSubFolder);

    addToPlayList(aSubFolder);

    myCurrent = myFirst;
    if(hasTarget || !aFileName.isEmpty()) {
        // set current item
        for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) {
            if(anItem->getPath() == aTarget) {
                myCurrent = anItem;
                if(myPlsFile.isNull()) {
                    addRecentFile(*anItem->getFileNode()); // append to recent files list
                }
                break;
            }
        }
    }

    anAutoLock.unlock();
    signals.onPlaylistChange();
}
コード例 #24
0
ファイル: StOutIZ3D.cpp プロジェクト: angelstudio/sview
bool StOutIZ3D::create() {
    StWindow::show();
    if(!StWindow::create()) {
        return false;
    }

    // initialize GL context
    myContext = StWindow::getContext();
    myContext->setMessagesQueue(myMsgQueue);
    const StHandle<StResourceManager>& aResMgr = getResourceManager();
    if(!myContext->isGlGreaterEqual(2, 0)) {
        myMsgQueue->pushError(stCString("OpenGL 2.0 is required by iZ3D Output"));
        myIsBroken = true;
        return true;
    }

    StWindow::stglMakeCurrent(ST_WIN_MASTER);
    myContext->stglSetVSync((StGLContext::VSync_Mode )StWindow::params.VSyncMode->getValue());
    StWindow::params.VSyncMode->signals.onChanged += stSlot(this, &StOutIZ3D::doSwitchVSync);

    // INIT iZ3D tables textures
    StAVImage aTableImg;
    StHandle<StResource> aTableOld = aResMgr->getResource(StString("textures") + SYS_FS_SPLITTER + "iz3dTableOld.png");
    uint8_t* aData     = NULL;
    int      aDataSize = 0;
    if(!aTableOld.isNull()
    && !aTableOld->isFile()
    &&  aTableOld->read()) {
        aData     = (uint8_t* )aTableOld->getData();
        aDataSize = aTableOld->getSize();
    }
    if(!aTableImg.load(!aTableOld.isNull() ? aTableOld->getPath() : StString(), StImageFile::ST_TYPE_PNG, aData, aDataSize)) {
        myMsgQueue->pushError(StString("iZ3D output - critical error:\n") + aTableImg.getState());
        myIsBroken = true;
        return true;
    }
    myTexTableOld.setMinMagFilter(*myContext, GL_NEAREST); // we need not linear filtrating for lookup-table!
    if(!myTexTableOld.init(*myContext, aTableImg.getPlane())) {
        myMsgQueue->pushError(stCString("iZ3D output - critical error:\nLookup-table initalization failed!"));
        myIsBroken = true;
        return true;
    }

    StHandle<StResource> aTableNew = aResMgr->getResource(StString("textures") + SYS_FS_SPLITTER + "iz3dTableNew.png");
    aData     = NULL;
    aDataSize = 0;
    if(!aTableNew.isNull()
    && !aTableNew->isFile()
    &&  aTableNew->read()) {
        aData     = (uint8_t* )aTableNew->getData();
        aDataSize = aTableNew->getSize();
    }
    if(!aTableImg.load(!aTableNew.isNull() ? aTableNew->getPath() : StString(), StImageFile::ST_TYPE_PNG, aData, aDataSize)) {
        myMsgQueue->pushError(StString("iZ3D output - critical error:\n") + aTableImg.getState());
        myIsBroken = true;
        return true;
    }
    myTexTableNew.setMinMagFilter(*myContext, GL_NEAREST); // we need not linear filtrating for lookup-table!
    if(!myTexTableNew.init(*myContext, aTableImg.getPlane())) {
        myMsgQueue->pushError(stCString("iZ3D output - critical error:\nLookup-table initalization failed!"));
        myIsBroken = true;
        return true;
    }

    // INIT shaders
    if(!myShaders.init(*myContext)) {
        myMsgQueue->pushError(stCString("iZ3D output - critical error:\nShaders initialization failed!"));
        myIsBroken = true;
        return true;
    }

    myIsBroken = false;
    return true;
}
コード例 #25
0
ファイル: StAndroidGlue.cpp プロジェクト: angelstudio/sview
StCString StAndroidGlue::getCommandIdName(StAndroidGlue::CommandId theCmd) {
    switch(theCmd) {
        case StAndroidGlue::CommandId_InputChanged:  return stCString("InputChanged");
        case StAndroidGlue::CommandId_WindowInit:    return stCString("WindowInit");
        case StAndroidGlue::CommandId_WindowTerm:    return stCString("WindowTerm");
        case StAndroidGlue::CommandId_WindowResize:  return stCString("WindowResize");
        case StAndroidGlue::CommandId_WindowRedraw:  return stCString("WindowRedraw");
        case StAndroidGlue::CommandId_FocusGained:   return stCString("FocusGained");
        case StAndroidGlue::CommandId_FocusLost:     return stCString("FocusLost");
        case StAndroidGlue::CommandId_ConfigChanged: return stCString("ConfigChanged");
        case StAndroidGlue::CommandId_LowMemory:     return stCString("LowMemory");
        case StAndroidGlue::CommandId_Start:         return stCString("Start");
        case StAndroidGlue::CommandId_Resume:        return stCString("Resume");
        case StAndroidGlue::CommandId_SaveState:     return stCString("SaveState");
        case StAndroidGlue::CommandId_Pause:         return stCString("Pause");
        case StAndroidGlue::CommandId_Stop:          return stCString("Stop");
        case StAndroidGlue::CommandId_Destroy:       return stCString("Destroy");
        case StAndroidGlue::CommandId_BackPressed:   return stCString("BackPressed");
        case StAndroidGlue::CommandId_WindowChanged: return stCString("WindowChanged");
    }
    return stCString("UNKNOWN");
}
コード例 #26
0
ファイル: StOutIZ3D.cpp プロジェクト: angelstudio/sview
void StOutIZ3D::stglDraw() {
    if(!StWindow::stglMakeCurrent(ST_WIN_MASTER)) {
        StWindow::signals.onRedraw(ST_DRAW_MONO);
        StThread::sleep(10);
        return;
    }

    myFPSControl.setTargetFPS(StWindow::getTargetFps());

    const StGLBoxPx aVPMaster = StWindow::stglViewport(ST_WIN_MASTER);
    const StGLBoxPx aVPSlave  = StWindow::stglViewport(ST_WIN_SLAVE);
    if(!StWindow::isStereoOutput() || myIsBroken) {
        if(myToCompressMem) {
            myFrBuffer->release(*myContext);
        }

        myContext->stglResizeViewport(aVPMaster);
        myContext->stglSetScissorRect(aVPMaster, false);
        StWindow::signals.onRedraw(ST_DRAW_LEFT);
        myContext->stglResetScissorRect();

        StWindow::stglMakeCurrent(ST_WIN_SLAVE);
        myContext->stglResizeViewport(aVPSlave);
        myContext->stglSetScissorRect(aVPSlave, false);
        myContext->core20fwd->glClearColor(0.729740052840723f, 0.729740052840723f, 0.729740052840723f, 0.0f);
        // clear the screen and the depth buffer
        myContext->core20fwd->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        myContext->core20fwd->glClearColor(0, 0, 0, 0);
        myContext->stglResetScissorRect();

        myFPSControl.sleepToTarget(); // decrease FPS to target by thread sleeps
        StWindow::stglSwap(ST_WIN_ALL);
        ++myFPSControl;
        return;
    }

    // resize FBO
    if(!myFrBuffer->initLazy(*myContext, aVPMaster.width(), aVPMaster.height(), StWindow::hasDepthBuffer())) {
        myMsgQueue->pushError(stCString("iZ3D output - critical error:\nFrame Buffer Object resize failed!"));
        myIsBroken = true;
        return;
    }

    // draw into virtual frame buffers (textures)
    myFrBuffer->setupViewPort(*myContext);    // we set TEXTURE sizes here
    myFrBuffer->bindBufferLeft(*myContext);
        StWindow::signals.onRedraw(ST_DRAW_LEFT);
    myFrBuffer->bindBufferRight(*myContext);
        StWindow::signals.onRedraw(ST_DRAW_RIGHT);
    myFrBuffer->unbindBufferRight(*myContext);

    // now draw to real screen buffer
    // clear the screen and the depth buffer
    myContext->stglResizeViewport(aVPMaster);
    myContext->stglSetScissorRect(aVPMaster, false);
    myContext->core20fwd->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    myContext->core20fwd->glDisable(GL_DEPTH_TEST);
    myContext->core20fwd->glDisable(GL_BLEND);

    StGLTexture& stTexTable = (myShaders.getMode() == StOutIZ3DShaders::IZ3D_TABLE_NEW) ? myTexTableNew : myTexTableOld;

    myShaders.master()->use(*myContext);
    myFrBuffer->bindMultiTexture(*myContext);
    stTexTable.bind(*myContext, GL_TEXTURE2);

    myFrBuffer->drawQuad(*myContext, myShaders.master());

    stTexTable.unbind(*myContext);
    myFrBuffer->unbindMultiTexture(*myContext);
    myShaders.master()->unuse(*myContext);
    myContext->stglResetScissorRect();

    StWindow::stglMakeCurrent(ST_WIN_SLAVE);
    myContext->stglResizeViewport(aVPSlave);
    myContext->stglSetScissorRect(aVPSlave, false);
    myContext->core20fwd->glClearColor(0.729740052840723f, 0.729740052840723f, 0.729740052840723f, 0.0f);
    // clear the screen and the depth buffer
    myContext->core20fwd->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    myContext->core20fwd->glClearColor(0, 0, 0, 0);

    myShaders.slave()->use(*myContext);
    myFrBuffer->bindMultiTexture(*myContext);
    stTexTable.bind(*myContext, GL_TEXTURE2);

    myFrBuffer->drawQuad(*myContext, myShaders.slave());

    stTexTable.unbind(*myContext);
    myFrBuffer->unbindMultiTexture(*myContext);
    myShaders.slave()->unuse(*myContext);
    myContext->stglResetScissorRect();

    myFPSControl.sleepToTarget(); // decrease FPS to target by thread sleeps
    StWindow::stglSwap(ST_WIN_ALL);
    ++myFPSControl;
    // make sure all GL changes in callback (in StDrawer) will fine
    StWindow::stglMakeCurrent(ST_WIN_MASTER);
}