コード例 #1
0
ファイル: DrawContext.cpp プロジェクト: mblewett/OmegaLib
void DrawContext::updateViewport()
{
    DisplaySystem* ds = renderer->getDisplaySystem();
    DisplayConfig& dcfg = ds->getDisplayConfig();

    int pvpx = 0;
    int pvpy = 0;
    int pvpw = tile->pixelSize[0];
    int pvph = tile->pixelSize[1];

    // Setup side-by-side stereo if needed.
    if(tile->stereoMode == DisplayTileConfig::SideBySide ||
        (tile->stereoMode == DisplayTileConfig::Default && 
        dcfg.stereoMode == DisplayTileConfig::SideBySide))
    {
        if(dcfg.forceMono)
        {
            // Runtime stereo disable switch
            viewport = Rect(pvpx, pvpy, pvpw, pvph);
        }
        else
        {
            // Do we want to invert stereo?
            bool invertStereo = ds->getDisplayConfig().invertStereo || tile->invertStereo; 

            if(eye == DrawContext::EyeLeft)
            {
                if(invertStereo)
                {
                    viewport = Rect(pvpx + pvpw / 2, pvpy, pvpw / 2, pvph);
                }
                else
                {
                    viewport = Rect(pvpx, pvpy, pvpw / 2, pvph);
                }
            }
            else if(eye == DrawContext::EyeRight)
            {
                if(invertStereo)
                {
                    viewport = Rect(pvpx, pvpy, pvpw / 2, pvph);
                }
                else
                {
                    viewport = Rect(pvpx + pvpw / 2, pvpy, pvpw / 2, pvph);
                }
            }
            else
            {
                viewport = Rect(pvpx, pvpy, pvpw, pvph);
            }
        }
    }
    //else
    //{
    //    viewport = Rect(pvpx, pvpy, pvpw, pvph);
    //}
}
コード例 #2
0
ファイル: DrawContext.cpp プロジェクト: mblewett/OmegaLib
DisplayTileConfig::StereoMode DrawContext::getCurrentStereoMode()
{
    DisplaySystem* ds = renderer->getDisplaySystem();
    DisplayConfig& dcfg = ds->getDisplayConfig();
    if(dcfg.forceMono) return DisplayTileConfig::Mono;
    if(tile->stereoMode == DisplayTileConfig::Default) return dcfg.stereoMode;
    return tile->stereoMode;
}
コード例 #3
0
ファイル: UiRenderPass.cpp プロジェクト: Ping-Hu/omegalib
void UiRenderPass::render(Renderer* client, const DrawContext& context)
{
    sLock.lock();
    myDrawTimeStat->startTiming();

    if(context.task == DrawContext::SceneDrawTask)
    {
        client->getRenderer()->beginDraw3D(context);
        glPushAttrib(GL_ALL_ATTRIB_BITS);

        // This is a bit of a hack. DIsable depth testing for ui stuff. We will take care of ordering.
        // This may lead to depth inconsistencies wrt the background scene when drawing 3d menus, but we want te
        // menus to always be visible and unoccluded by geometry.
        glDisable(GL_DEPTH_TEST);

        ui::Container* ui = myUiRoot;
        Renderable* uiRenderable = ui->getRenderable(client);
        if(uiRenderable != NULL)
        {
            uiRenderable->draw(context);
        }

        glPopAttrib();
        client->getRenderer()->endDraw();
    }
    else if(context.task == DrawContext::OverlayDrawTask)
    {
        Vector2i displaySize;
        // check if the tile is part of a canvas (a multi-tile grid). If it is,
        // get the canvas resolution. Otherwise simply use the tile resolution.
        if(context.tile->isInGrid)
        {
            DisplaySystem* ds = SystemManager::instance()->getDisplaySystem();
            displaySize = ds->getDisplayConfig().getCanvasRect().size();
        }
        else
        {
            displaySize = context.tile->pixelSize;
        }

        client->getRenderer()->beginDraw2D(context);
        glPushAttrib(GL_ALL_ATTRIB_BITS);

        Renderable* uiRenderable = myUiRoot->getRenderable(client);
        if(uiRenderable != NULL)
        {
            uiRenderable->draw(context);
        }

        glPopAttrib();
        client->getRenderer()->endDraw();
    }

    myDrawTimeStat->stopTiming();
    sLock.unlock();
}
コード例 #4
0
ファイル: DrawContext.cpp プロジェクト: mblewett/OmegaLib
void DrawContext::setupInterleaver()
{
    DisplaySystem* ds = renderer->getDisplaySystem();
    DisplayConfig& dcfg = ds->getDisplayConfig();

    // Setup the stencil buffer if needed.
    // The stencil buffer is set up if th tile is using an interleaved mode (line or pixel)
    // or if the tile is left in default mode and the global stereo mode is an interleaved mode
    if(tile->stereoMode == DisplayTileConfig::LineInterleaved ||
        tile->stereoMode == DisplayTileConfig::ColumnInterleaved ||
        tile->stereoMode == DisplayTileConfig::PixelInterleaved ||
        (tile->stereoMode == DisplayTileConfig::Default && (
                dcfg.stereoMode == DisplayTileConfig::LineInterleaved ||
                dcfg.stereoMode == DisplayTileConfig::ColumnInterleaved ||
                dcfg.stereoMode == DisplayTileConfig::PixelInterleaved)))
    {
        if(!stencilInitialized)
        {
            initializeStencilInterleaver(tile->pixelSize[0], tile->pixelSize[1]);
            stencilInitialized = true;
        }
    }
    // Configure stencil test when rendering interleaved with stencil is enabled.
    if(stencilInitialized)
    {
        if(dcfg.forceMono || eye == DrawContext::EyeCyclop)
        {
            // Disable stencil
            glStencilFunc(GL_ALWAYS,0x2,0x2); // to avoid interaction with stencil content
        }
        else
        {
            //glStencilMask(0x2);
            if(eye == DrawContext::EyeLeft)
            {
                glStencilFunc(GL_NOTEQUAL,0x2,0x2); // draws if stencil <> 1
            }
            else if(eye == DrawContext::EyeRight)
            {
                glStencilFunc(GL_EQUAL,0x2,0x2); // draws if stencil <> 0
            }
        }
    }
}
コード例 #5
0
ファイル: MouseManipulator.cpp プロジェクト: Ping-Hu/omegalib
void MouseManipulator::handleEvent(const Event& evt)
{
	if(myNode == NULL) return;
	if(evt.getServiceType() == Service::Pointer && !evt.isProcessed())
	{
		myPointerButton1Pressed = false;
		myPointerButton2Pressed = false;
		myPointerEventReceived = true;
		
		myPointerEventData = 0;
		// Process mouse axes.
		DisplaySystem* ds = SystemManager::instance()->getDisplaySystem();
		Vector2i resolution = ds->getDisplayConfig().getCanvasRect().size();

		float curX = evt.getPosition().x() / resolution[0];
		float curY = evt.getPosition().y() / resolution[1];

		float dx = (curX - myLastPointerPosition[0]) * myPointerAxisMultiplier;
		float dy = -(curY - myLastPointerPosition[1]) * myPointerAxisMultiplier;

		myPointerPosition[0] = dx;
		myPointerPosition[1] = dy;

		// Save current (normalized) pointer position.
		myLastPointerPosition[0] = curX;
		myLastPointerPosition[1] = curY;


		// We just care about Up / Down events.
		//if(evt.getType() != Event::Move)
		{
			myPointerEventType = evt.getType();
		}

		if(evt.isFlagSet(myMoveButtonFlag)) myPointerButton1Pressed = true;
		if(evt.isFlagSet(myRotateButtonFlag)) myPointerButton2Pressed = true;

		if(myPointerButton1Pressed || myPointerButton2Pressed) evt.setProcessed();
		
		//if(evt.getType() == Event::Zoom) myPointerEventData = evt.getExtraDataInt(0);
	}
}
コード例 #6
0
void WandEmulationService::updateAxes(const Event& evt)
{
    float pointerAxisMultiplier = 100.0f;

    // Process mouse axes.
    DisplaySystem* ds = SystemManager::instance()->getDisplaySystem();
    Vector2i resolution = ds->getDisplayConfig().getCanvasRect().size();

    float curX = evt.getPosition().x() / resolution[0];
    float curY = evt.getPosition().y() / resolution[1];

    float dx = (curX - myLastPointerPosition[0]) * pointerAxisMultiplier;
    float dy = -(curY - myLastPointerPosition[1]) * pointerAxisMultiplier;

    myXAxis = dx;
    myYAxis = dy;

    // Save current (normalized) pointer position.
    myLastPointerPosition[0] = curX;
    myLastPointerPosition[1] = curY;
}
コード例 #7
0
void WandPointerSwitcher::poll()
{
    // If the engine has not been initialized yet, exit.
    if(Engine::instance() == NULL) return;

    // If the Ui Module is not running, this service has nothing to do. Exit.
    UiModule* uim = UiModule::instance();
    if(uim == NULL) return;


    lockEvents();
    int numEvts = getManager()->getAvailableEvents();
    for(int i = 0; i < numEvts; i++)
    {
        Event* evt = getEvent(i);
        // Process mocap events.
        if(evt->getServiceType() == Service::Wand &&
            !evt->isExtraDataNull(2) && !evt->isExtraDataNull(3))
        {
            Vector2f out;
            DisplaySystem* ds = SystemManager::instance()->getDisplaySystem();
            DisplayConfig& dcfg = ds->getDisplayConfig();
            const Rect& cr = dcfg.getCanvasRect();

            out[0] = evt->getExtraDataFloat(2) * dcfg.displayResolution[0] - cr.x();
            out[1] = evt->getExtraDataFloat(3) * dcfg.displayResolution[1] - cr.y();
            
            if(pointIntersectsAnyContainer(out, uim->getUi()))
            {
                evt->setPosition(Vector3f(out[0], out[1], 0));
                evt->setServiceType(Service::Pointer);
                // If the event is an Update event, also convert it to a Move event, since
                // pointer handling code expects that.
                if(evt->getType() == Event::Update) evt->resetType(Event::Move);            
            }
        }
    }

    unlockEvents();
}
コード例 #8
0
ファイル: DrawContext.cpp プロジェクト: mblewett/OmegaLib
void DrawContext::updateTransforms(
    const AffineTransform3& head, 
    const AffineTransform3& view, 
    float eyeSeparation,
    float nearZ,
    float farZ)
{
    DisplaySystem* ds = renderer->getDisplaySystem();
    DisplayConfig& dcfg = ds->getDisplayConfig();
    
    Vector3f pa = tile->bottomLeft;
    Vector3f pb = tile->bottomRight;
    Vector3f pc = tile->topLeft;
    
    if(tile->isHMD)
    {
        pa = head * pa;
        pb = head * pb;
        pc = head * pc;
    }

    // half eye separation
    float hes = eyeSeparation / 2;
    Vector3f pe = Vector3f::Zero();
    switch(eye)
    {
    case EyeLeft:
        pe[0] = -hes;
        break;
    case EyeRight:
        pe[0] = hes;
        break;
    }

    // Transform eye with head position / orientation. After this, eye position
    // and tile coordinates are all in the same reference frame.
    if(dcfg.panopticStereoEnabled)
    {
        // CAVE2 SIMPLIFICATION: We are just interested in adjusting the observer yaw
        AffineTransform3 ht = AffineTransform3::Identity();
        ht.translate(head.translation());
        pe = ht.rotate(
            AngleAxis(-tile->yaw * Math::DegToRad, Vector3f::UnitY())) * pe;
    }
    else
    {
        pe = head * pe;
    }

    Vector3f vr = pb - pa;
    Vector3f vu = pc - pa;
    Vector3f vn = vr.cross(vu);

    Vector2f viewSize = viewMax - viewMin;

    // Update tile corners based on local view position and size
    pa = pa + vr * viewMin[0] + vu * viewMin[1];
    pb = pa + vr * viewSize[0];
    pc = pa + vu * viewSize[1];

    vr.normalize();
    vu.normalize();
    vn.normalize();

    // Compute the screen corner vectors.
    Vector3f va = pa - pe;
    Vector3f vb = pb - pe;
    Vector3f vc = pc - pe;

    // Find distance from eye to screen plane.
    //Vector3f tm = pe - pa;
    float d = -(vn.dot(va));

    // Find the extent of the perpendicular projection.
    float l = vr.dot(va) * nearZ / d;
    float r = vr.dot(vb) * nearZ / d;
    float b = vu.dot(va) * nearZ / d;
    float t = vu.dot(vc) * nearZ / d;

    // Compute the projection matrix. 
    Transform3 oax;
    oax.setIdentity();
    oax(0,0) = 2 * nearZ / (r - l);
    oax(0,2) = (r + l) / (r - l);
    oax(1,1) = 2 * nearZ / (t - b);
    oax(1,2) = (t + b) / (t - b);
    oax(2,2) = - (farZ + nearZ) / (farZ - nearZ);
    oax(2,3) = - (2 * farZ * nearZ) / (farZ - nearZ);
    oax(3,2) = - 1;
    oax(3,3) = 0;

    projection = oax; 
    
    // Compute the view matrix. The view matrix has two main components:
    // - the navigational component given by myViewTransform, converts points
    //   from world space to 'camera' space (origin is determined by camera position / orientation)
    // - the screen plane component, given by the current tile orientation and head position.
    //   this component converts points from camera space to screen-oriented eye space 
    //   (that is, origin is at eye position, and orientation is determined by the screen plane,
    //   with positive Y being screen up vector, X being screen right vector and Z being screen normal)
    AffineTransform3 newBasis;
    newBasis.setIdentity();
    newBasis.data()[0] = vr[0];
    newBasis.data()[1] = vu[0];
    newBasis.data()[2] = vn[0];

    newBasis.data()[4] = vr[1];
    newBasis.data()[5] = vu[1];
    newBasis.data()[6] = vn[1];

    newBasis.data()[8] = vr[2];
    newBasis.data()[9] = vu[2];
    newBasis.data()[10] = vn[2];

    newBasis = newBasis.translate(-pe);

    modelview = newBasis * view;
}
コード例 #9
0
ファイル: DrawContext.cpp プロジェクト: mblewett/OmegaLib
void DrawContext::initializeStencilInterleaver(int gliWindowWidth, int gliWindowHeight)
{
    DisplaySystem* ds = renderer->getDisplaySystem();
    DisplayConfig& dcfg = ds->getDisplayConfig();

    GLint gliStencilBits;
    glGetIntegerv(GL_STENCIL_BITS,&gliStencilBits);

    //EqualizerDisplaySystem* ds = dynamic_cast<EqualizerDisplaySystem*>(SystemManager::instance()->getDisplaySystem());
    DisplayTileConfig::StereoMode stereoMode = tile->stereoMode;
    if(stereoMode == DisplayTileConfig::Default) stereoMode = dcfg.stereoMode;

    // seting screen-corresponding geometry
    glViewport(0,0,gliWindowWidth,gliWindowHeight);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.5,gliWindowWidth + 0.5,0.5,gliWindowHeight + 0.5);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
        
        
    // clearing and configuring stencil drawing
    glDrawBuffer(GL_BACK);
    glEnable(GL_STENCIL_TEST);
    glStencilMask(0x2);
    glClearStencil(0);
    glClear(GL_STENCIL_BUFFER_BIT);
    glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE); // colorbuffer is copied to stencil
    glDisable(GL_DEPTH_TEST);
    glStencilFunc(GL_ALWAYS,0xFF,0xFF); // to avoid interaction with stencil content
    
    // drawing stencil pattern
    glColor4f(1,1,1,0);	// alpha is 0 not to interfere with alpha tests
    
    if(stereoMode == DisplayTileConfig::LineInterleaved)
    {
        // Do we want to invert stereo?
        bool invertStereo = ds->getDisplayConfig().invertStereo || tile->invertStereo; 
        int startOffset = invertStereo ? -1 : -2;

        for(float gliY = startOffset; gliY <= gliWindowHeight; gliY += 2)
        {
            glLineWidth(1);
            glBegin(GL_LINES);
                glVertex2f(0, gliY);
                glVertex2f(gliWindowWidth, gliY);
            glEnd();	
        }
    }	
    else if(stereoMode == DisplayTileConfig::ColumnInterleaved)
    {
        // Do we want to invert stereo?
        bool invertStereo = ds->getDisplayConfig().invertStereo || tile->invertStereo; 
        int startOffset = invertStereo ? -1 : -2;

        for(float gliX = startOffset; gliX <= gliWindowWidth; gliX += 2)
        {
            glLineWidth(1);
            glBegin(GL_LINES);
                glVertex2f(gliX, 0);
                glVertex2f(gliX,gliWindowHeight);
            glEnd();	
        }
    }
    else if(stereoMode == DisplayTileConfig::PixelInterleaved)
    {
        for(float gliX=-2; gliX<=gliWindowWidth; gliX+=2)
        {
            glLineWidth(1);
            glBegin(GL_LINES);
                glVertex2f(gliX, 0);
                glVertex2f(gliX, gliWindowHeight);
            glEnd();	
        }
    }
    glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); // disabling changes in stencil buffer
    glFlush();
}