bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig)
{
	///QUESTION - what is returned bool for???  Are we happy with this true, if not config.
    const ovrD3D9Config * config = (const ovrD3D9Config*)apiConfig;
    if (!config)                return true; 
    if (!config->D3D9.pDevice)  return false;

    if (System::DirectDisplayEnabled())
    {
        Ptr<IUnknown> ovrDevice;
        if (config->D3D9.pDevice->QueryInterface(IID_OVRDirect3DDevice9EX, (void**)&ovrDevice.GetRawRef()) == E_NOINTERFACE)
        {
            OVR_DEBUG_LOG_TEXT(("ovr_Initialize() or ovr_InitializeRenderingShim() wasn't called before the D3D9 device was created."));
        }
    }

	//Glean all the required variables from the input structures
	Device         = config->D3D9.pDevice;
    SwapChain      = config->D3D9.pSwapChain;
	ScreenSize     = config->D3D9.Header.BackBufferSize;

	GfxState = *new GraphicsState(Device, RState.DistortionCaps);

	CreateVertexDeclaration();
	CreateDistortionShaders();
	CreateDistortionModels();

    return true;
}
Ejemplo n.º 2
0
void HMDDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor)
{
    // For now we'll assume the Rift DK1 is attached in extended monitor mode. Ultimately we need to
    // use XFree86 to enumerate X11 screens in case the Rift is attached as a separate screen. We also
    // need to be able to read the EDID manufacturer product code to be able to differentiate between
    // Rift models.

    bool foundHMD = false;

    Display* display = XOpenDisplay(NULL);
    if (display && XineramaIsActive(display))
    {
        int numberOfScreens;
        XineramaScreenInfo* screens = XineramaQueryScreens(display, &numberOfScreens);

        for (int i = 0; i < numberOfScreens; i++)
        {
            XineramaScreenInfo screenInfo = screens[i];

            if (screenInfo.width == 1280 && screenInfo.height == 800)
            {
                String deviceName = "OVR0001";

                HMDDeviceCreateDesc hmdCreateDesc(this, deviceName, i);
                hmdCreateDesc.SetScreenParameters(screenInfo.x_org, screenInfo.y_org, 1280, 800, 0.14976f, 0.0936f);

                OVR_DEBUG_LOG_TEXT(("DeviceManager - HMD Found %s - %d\n",
                                    deviceName.ToCStr(), i));

                // Notify caller about detected device. This will call EnumerateAddDevice
                // if the this is the first time device was detected.
                visitor.Visit(hmdCreateDesc);
                foundHMD = true;
                break;
            }
        }

        XFree(screens);
    }


    // Real HMD device is not found; however, we still may have a 'fake' HMD
    // device created via SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo.
    // Need to find it and set 'Enumerated' to true to avoid Removal notification.
    if (!foundHMD)
    {
        Ptr<DeviceCreateDesc> hmdDevDesc = getManager()->FindDevice("", Device_HMD);
        if (hmdDevDesc)
            hmdDevDesc->Enumerated = true;
    }
}
Texture* RenderDevice::CreateTexture(int format, int width, int height, const void* data, int mipcount)
{
    OVR_UNUSED(mipcount);

    DXGI_FORMAT d3dformat;
    int         bpp;
    switch(format & Texture_TypeMask)
    {
    case Texture_RGBA:
        bpp = 4;
        d3dformat = DXGI_FORMAT_R8G8B8A8_UNORM;
        break;
    case Texture_Depth:
        bpp = 0;
        d3dformat = DXGI_FORMAT_D32_FLOAT;
        break;
    default:
        return NULL;
    }

    int samples = (format & Texture_SamplesMask);
    if (samples < 1)
    {
        samples = 1;
    }

    Texture* NewTex = new Texture(this, format, width, height);
    NewTex->Samples = samples;

    D3D11_TEXTURE2D_DESC dsDesc;
    dsDesc.Width     = width;
    dsDesc.Height    = height;
    dsDesc.MipLevels = (format == (Texture_RGBA | Texture_GenMipmaps) && data) ? GetNumMipLevels(width, height) : 1;
    dsDesc.ArraySize = 1;
    dsDesc.Format    = d3dformat;
    dsDesc.SampleDesc.Count = samples;
    dsDesc.SampleDesc.Quality = 0;
    dsDesc.Usage     = D3D11_USAGE_DEFAULT;
    dsDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    dsDesc.CPUAccessFlags = 0;
    dsDesc.MiscFlags      = 0;

    if (format & Texture_RenderTarget)
    {
        if ((format & Texture_TypeMask) == Texture_Depth)            
        { // We don't use depth textures, and creating them in d3d10 requires different options.
            dsDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
        }
        else
        {
            dsDesc.BindFlags |= D3D11_BIND_RENDER_TARGET;
        }
    }

    HRESULT hr = Device->CreateTexture2D(&dsDesc, NULL, &NewTex->Tex.GetRawRef());
    if (FAILED(hr))
    {
        OVR_DEBUG_LOG_TEXT(("Failed to create 2D D3D texture."));
        NewTex->Release();
        return NULL;
    }
    if (dsDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE)
    {
        Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef());
    }

    if (data)
    {
        Context->UpdateSubresource(NewTex->Tex, 0, NULL, data, width * bpp, width * height * bpp);
        if (format == (Texture_RGBA | Texture_GenMipmaps))
        {
            int srcw = width, srch = height;
            int level = 0;
            uint8_t* mipmaps = NULL;
            do
            {
                level++;
                int mipw = srcw >> 1;
                if (mipw < 1)
                {
                    mipw = 1;
                }
                int miph = srch >> 1;
                if (miph < 1)
                {
                    miph = 1;
                }
                if (mipmaps == NULL)
                {
                    mipmaps = (uint8_t*)OVR_ALLOC(mipw * miph * 4);
                }
                FilterRgba2x2(level == 1 ? (const uint8_t*)data : mipmaps, srcw, srch, mipmaps);
                Context->UpdateSubresource(NewTex->Tex, level, NULL, mipmaps, mipw * bpp, miph * bpp);
                srcw = mipw;
                srch = miph;
            }
            while(srcw > 1 || srch > 1);

            if (mipmaps != NULL)
            {
                OVR_FREE(mipmaps);
            }
        }
    }
Ejemplo n.º 4
0
void HMDDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor)
{
    MonitorSet monitors;
    monitors.MonitorCount = 0;
    // Get all the monitor handles 
    EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&monitors);

    bool foundHMD = false;
    
   // DeviceManager* manager = getManager();
    DISPLAY_DEVICE dd, ddm;
    UINT           i, j;    

    for (i = 0; 
        (ZeroMemory(&dd, sizeof(dd)), dd.cb = sizeof(dd),
        EnumDisplayDevices(0, i, &dd, 0)) != 0;  i++)
    {
        
        /*
        wchar_t buff[500], flagsBuff[200];
        
        swprintf_s(buff, 500, L"\nDEV: \"%s\" \"%s\" 0x%08x=%s\n     \"%s\" \"%s\"\n",
            dd.DeviceName, dd.DeviceString,
            dd.StateFlags, FormatDisplayStateFlags(flagsBuff, 200, dd.StateFlags),
            dd.DeviceID, dd.DeviceKey);
        ::OutputDebugString(buff);
        */

        for (j = 0; 
            (ZeroMemory(&ddm, sizeof(ddm)), ddm.cb = sizeof(ddm),
            EnumDisplayDevices(dd.DeviceName, j, &ddm, 0)) != 0;  j++)
        {
            /*
            wchar_t mbuff[500];
            swprintf_s(mbuff, 500, L"MON: \"%s\" \"%s\" 0x%08x=%s\n     \"%s\" \"%s\"\n",
                ddm.DeviceName, ddm.DeviceString,
                ddm.StateFlags, FormatDisplayStateFlags(flagsBuff, 200, ddm.StateFlags),
                ddm.DeviceID, ddm.DeviceKey);
            ::OutputDebugString(mbuff);
            */

            // Our monitor hardware has string "RTD2205" in it
            // Nate's device "CVT0003"
            if (wcsstr(ddm.DeviceID, L"RTD2205") || 
                wcsstr(ddm.DeviceID, L"CVT0003") || 
                wcsstr(ddm.DeviceID, L"MST0030") ||
                wcsstr(ddm.DeviceID, L"OVR00") ) // Part of Oculus EDID.
            {
                String deviceId(ddm.DeviceID);
                String displayDeviceName(ddm.DeviceName);

                // The default monitor coordinates
                int mx      = 0;
                int my      = 0;
                int mwidth  = 1280;
                int mheight = 800;

                // Find the matching MONITORINFOEX for this device so we can get the 
                // screen coordinates
                MONITORINFOEX info;
                for (int m=0; m < monitors.MonitorCount; m++)
                {
                    info.cbSize = sizeof(MONITORINFOEX);
                    GetMonitorInfo(monitors.Monitors[m], &info);
                    if (_tcsstr(ddm.DeviceName, info.szDevice) == ddm.DeviceName)
                    {   // If the device name starts with the monitor name
                        // then we found the matching DISPLAY_DEVICE and MONITORINFO
                        // so we can gather the monitor coordinates
                        mx = info.rcMonitor.left;
                        my = info.rcMonitor.top;
                        //mwidth = info.rcMonitor.right - info.rcMonitor.left;
                        //mheight = info.rcMonitor.bottom - info.rcMonitor.top;
                        break;
                    }
                }

                HMDDeviceCreateDesc hmdCreateDesc(this, deviceId, displayDeviceName);
				
				if (wcsstr(ddm.DeviceID, L"OVR0002"))
				{
					hmdCreateDesc.SetScreenParameters(mx, my, 1920, 1080, 0.12096f, 0.06804f);
				}
				else
				{
					if (hmdCreateDesc.Is7Inch())
					{
						// Physical dimension of SLA screen.
						hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.14976f, 0.0936f);
					}
					else
					{
						hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.12096f, 0.0756f);
					}
				}


                OVR_DEBUG_LOG_TEXT(("DeviceManager - HMD Found %s - %s\n",
                                    deviceId.ToCStr(), displayDeviceName.ToCStr()));

                // Notify caller about detected device. This will call EnumerateAddDevice
                // if the this is the first time device was detected.
                visitor.Visit(hmdCreateDesc);
                foundHMD = true;
                break;
            }
        }
    }

    // Real HMD device is not found; however, we still may have a 'fake' HMD
    // device created via SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo.
    // Need to find it and set 'Enumerated' to true to avoid Removal notification.
    if (!foundHMD)
    {
        Ptr<DeviceCreateDesc> hmdDevDesc = getManager()->FindDevice("", Device_HMD);
        if (hmdDevDesc)
            hmdDevDesc->Enumerated = true;
    }
}
bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRender,
	                      OVR::Render::Scene* pScene,
                          OVR::Array<Ptr<CollisionModel> >* pCollisions,
	                      OVR::Array<Ptr<CollisionModel> >* pGroundCollisions,
                          bool srgbAware /*= false*/,
                          bool anisotropic /*= false*/)
{
    if(pXmlDocument->LoadFile(fileName) != 0)
    {
        return false;
    }

    // Extract the relative path to our working directory for loading textures
    filePath[0] = 0;
    intptr_t pos = 0;
	intptr_t len = strlen(fileName);
    for(intptr_t i = len; i > 0; i--)
    {
        if (fileName[i-1]=='\\' || fileName[i-1]=='/')
        {
            memcpy(filePath, fileName, i);
            filePath[i] = 0;
            break;
        }        
    }    

    // Load the textures
	OVR_DEBUG_LOG_TEXT(("Loading textures..."));
    XMLElement* pXmlTexture = pXmlDocument->FirstChildElement("scene")->FirstChildElement("textures");
    OVR_ASSERT(pXmlTexture);
    if (pXmlTexture)
    {
        pXmlTexture->QueryIntAttribute("count", &textureCount);
        pXmlTexture = pXmlTexture->FirstChildElement("texture");
    }

    for(int i = 0; i < textureCount; ++i)
    {
        const char* textureName = pXmlTexture->Attribute("fileName");
		intptr_t    dotpos = strcspn(textureName, ".");
        char        fname[300];

		if (pos == len)
		{            
			OVR_sprintf(fname, 300, "%s", textureName);
		}
		else
		{
			OVR_sprintf(fname, 300, "%s%s", filePath, textureName);
		}

        int textureLoadFlags = 0;
        textureLoadFlags |= srgbAware ? TextureLoad_SrgbAware : 0;
        textureLoadFlags |= anisotropic ? TextureLoad_Anisotropic : 0;

        SysFile* pFile = new SysFile(fname);
		Ptr<Texture> texture;
		if (textureName[dotpos + 1] == 'd' || textureName[dotpos + 1] == 'D')
		{
			// DDS file
            Texture* tmp_ptr = LoadTextureDDSTopDown(pRender, pFile, textureLoadFlags);
			if(tmp_ptr)
			{
				texture.SetPtr(*tmp_ptr);
			}
		}
		else
		{
            Texture* tmp_ptr = LoadTextureTgaTopDown(pRender, pFile, textureLoadFlags, 255);
			if(tmp_ptr)
			{
				texture.SetPtr(*tmp_ptr);
			}
		}

        Textures.PushBack(texture);
		pFile->Close();
		pFile->Release();
        pXmlTexture = pXmlTexture->NextSiblingElement("texture");
    }
	OVR_DEBUG_LOG_TEXT(("Done.\n"));

    // Load the models
	pXmlDocument->FirstChildElement("scene")->FirstChildElement("models")->
		          QueryIntAttribute("count", &modelCount);
	
		OVR_DEBUG_LOG(("Loading models... %i models to load...", modelCount));
    XMLElement* pXmlModel = pXmlDocument->FirstChildElement("scene")->
		                                  FirstChildElement("models")->FirstChildElement("model");
    for(int i = 0; i < modelCount; ++i)
    {
		if (i % 15 == 0)
		{
			OVR_DEBUG_LOG_TEXT(("%i models remaining...", modelCount - i));
		}
        const char* name = pXmlModel->Attribute("name");
        Models.PushBack(*new Model(Prim_Triangles, name));
        bool isCollisionModel = false;
        pXmlModel->QueryBoolAttribute("isCollisionModel", &isCollisionModel);
        Models[i]->IsCollisionModel = isCollisionModel;
		if (isCollisionModel)
		{
			Models[i]->Visible = false;
		}

        bool tree_c = (strcmp(name, "tree_C") == 0) || (strcmp(name, "Object03") == 0);

        //read the vertices
        OVR::Array<Vector3f> *vertices = new OVR::Array<Vector3f>();
        ParseVectorString(pXmlModel->FirstChildElement("vertices")->FirstChild()->
			              ToText()->Value(), vertices);

		for (unsigned int vertexIndex = 0; vertexIndex < vertices->GetSize(); ++vertexIndex)
		{
			vertices->At(vertexIndex).x *= -1.0f;

            if (tree_c)
            {   // Move the terrace tree closer to the house
                vertices->At(vertexIndex).z += 0.5;
            }
		}

        //read the normals
        OVR::Array<Vector3f> *normals = new OVR::Array<Vector3f>();
        ParseVectorString(pXmlModel->FirstChildElement("normals")->FirstChild()->
			              ToText()->Value(), normals);

		for (unsigned int normalIndex = 0; normalIndex < normals->GetSize(); ++normalIndex)
		{
			normals->At(normalIndex).z *= -1.0f;
		}

        //read the textures
        OVR::Array<Vector3f> *diffuseUVs = new OVR::Array<Vector3f>();
        OVR::Array<Vector3f> *lightmapUVs = new OVR::Array<Vector3f>();
        int         diffuseTextureIndex = -1;
        int         lightmapTextureIndex = -1;
        XMLElement* pXmlCurMaterial = pXmlModel->FirstChildElement("material");

        while(pXmlCurMaterial != NULL)
        {
            if(pXmlCurMaterial->Attribute("name", "diffuse"))
            {
                pXmlCurMaterial->FirstChildElement("texture")->
					             QueryIntAttribute("index", &diffuseTextureIndex);
                if(diffuseTextureIndex > -1)
                {
                    ParseVectorString(pXmlCurMaterial->FirstChildElement("texture")->
						              FirstChild()->ToText()->Value(), diffuseUVs, true);
                }
            }
            else if(pXmlCurMaterial->Attribute("name", "lightmap"))
            {
                pXmlCurMaterial->FirstChildElement("texture")->
					                               QueryIntAttribute("index", &lightmapTextureIndex);
                if(lightmapTextureIndex > -1)
                {
                    XMLElement* firstChildElement = pXmlCurMaterial->FirstChildElement("texture");
                    XMLNode* firstChild = firstChildElement->FirstChild();
                    XMLText* text = firstChild->ToText();
                    const char* value = text->Value();
                    ParseVectorString(value, lightmapUVs, true);
                }
            }

            pXmlCurMaterial = pXmlCurMaterial->NextSiblingElement("material");
        }

        //set up the shader
        Ptr<ShaderFill> shader = *new ShaderFill(*pRender->CreateShaderSet());
        shader->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Vertex, VShader_MVP));
        if(diffuseTextureIndex > -1)
        {
            shader->SetTexture(0, Textures[diffuseTextureIndex]);
            if(lightmapTextureIndex > -1)
            {
                shader->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_MultiTexture));
                shader->SetTexture(1, Textures[lightmapTextureIndex]);
            }
            else
            {
                shader->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_Texture));
            }
        }
        else
        {
            shader->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_LitGouraud));
        }
        Models[i]->Fill = shader;

        //add all the vertices to the model
        const size_t numVerts = vertices->GetSize();
        for(size_t v = 0; v < numVerts; ++v)
        {
            if(diffuseTextureIndex > -1)
            {
                if(lightmapTextureIndex > -1)
                {
                    Models[i]->AddVertex(vertices->At(v).z, vertices->At(v).y, vertices->At(v).x, Color(255, 255, 255),
                                          diffuseUVs->At(v).x, diffuseUVs->At(v).y, lightmapUVs->At(v).x, lightmapUVs->At(v).y,
                                          normals->At(v).x, normals->At(v).y, normals->At(v).z);
                }
                else
                {
                    Models[i]->AddVertex(vertices->At(v).z, vertices->At(v).y, vertices->At(v).x, Color(255, 255, 255),
                                          diffuseUVs->At(v).x, diffuseUVs->At(v).y, 0, 0,
                                          normals->At(v).x, normals->At(v).y, normals->At(v).z);
                }
            }
            else
            {
                Models[i]->AddVertex(vertices->At(v).z, vertices->At(v).y, vertices->At(v).x, Color(255, 255, 255, 255),
                                      0, 0, 0, 0,
                                      normals->At(v).x, normals->At(v).y, normals->At(v).z);
            }
        }

        // Read the vertex indices for the triangles
        const char* indexStr = pXmlModel->FirstChildElement("indices")->
                                          FirstChild()->ToText()->Value();
        
        size_t stringLength = strlen(indexStr);

        for(size_t j = 0; j < stringLength; )
        {
            size_t k = j + 1;
            for(; k < stringLength; ++k)
            {
                if (indexStr[k] == ' ')
                    break;                
            }
            char text[20];
            for(size_t l = 0; l < k - j; ++l)
            {
                text[l] = indexStr[j + l];
            }
            text[k - j] = '\0';

            Models[i]->Indices.PushBack((unsigned short)atoi(text));
            j = k + 1;
        }

        // Reverse index order to match original expected orientation
        Array<uint16_t>& indices    = Models[i]->Indices;
        size_t         indexCount = indices.GetSize();         

        for (size_t revIndex = 0; revIndex < indexCount/2; revIndex++)
        {
            unsigned short itemp               = indices[revIndex];
            indices[revIndex]                  = indices[indexCount - revIndex - 1];
            indices[indexCount - revIndex - 1] = itemp;            
        }

        delete vertices;
        delete normals;
        delete diffuseUVs;
        delete lightmapUVs;

        pScene->World.Add(Models[i]);
        pScene->Models.PushBack(Models[i]);
        pXmlModel = pXmlModel->NextSiblingElement("model");
    }
	OVR_DEBUG_LOG(("Done."));

    //load the collision models
	OVR_DEBUG_LOG(("Loading collision models... "));
    XMLElement* pXmlCollisionModel = pXmlDocument->FirstChildElement("scene")->FirstChildElement("collisionModels");
    if (pXmlCollisionModel)
    {
		pXmlCollisionModel->QueryIntAttribute("count", &collisionModelCount);
        pXmlCollisionModel = pXmlCollisionModel->FirstChildElement("collisionModel");
    }

    XMLElement* pXmlPlane = NULL;
    for(int i = 0; i < collisionModelCount; ++i)
    {
        Ptr<CollisionModel> cm = *new CollisionModel();
        int planeCount = 0;
        
        OVR_ASSERT(pXmlCollisionModel != NULL); // collisionModelCount should guarantee this.
        if (pXmlCollisionModel)
        {
        pXmlCollisionModel->QueryIntAttribute("planeCount", &planeCount);

        pXmlPlane = pXmlCollisionModel->FirstChildElement("plane");
        for(int j = 0; j < planeCount; ++j)
        {
            Vector3f norm;
            pXmlPlane->QueryFloatAttribute("nx", &norm.x);
            pXmlPlane->QueryFloatAttribute("ny", &norm.y);
            pXmlPlane->QueryFloatAttribute("nz", &norm.z);
            float D;
            pXmlPlane->QueryFloatAttribute("d", &D);
            D -= 0.5f;
            if (i == 26)
                D += 0.5f;  // tighten the terrace collision so player can move right up to rail
            Planef p(norm.z, norm.y, norm.x * -1.0f, D);
            cm->Add(p);
            pXmlPlane = pXmlPlane->NextSiblingElement("plane");
        }

        if (pCollisions)
        pCollisions->PushBack(cm);
        pXmlCollisionModel = pXmlCollisionModel->NextSiblingElement("collisionModel");
    }
    }
	OVR_DEBUG_LOG(("done."));

    //load the ground collision models
	OVR_DEBUG_LOG(("Loading ground collision models..."));
    pXmlCollisionModel = pXmlDocument->FirstChildElement("scene")->FirstChildElement("groundCollisionModels");
    OVR_ASSERT(pXmlCollisionModel);
    if (pXmlCollisionModel)
    {
		pXmlCollisionModel->QueryIntAttribute("count", &groundCollisionModelCount);
        pXmlCollisionModel = pXmlCollisionModel->FirstChildElement("collisionModel");

    pXmlPlane = NULL;
    for(int i = 0; i < groundCollisionModelCount; ++i)
    {
        Ptr<CollisionModel> cm = *new CollisionModel();
        int planeCount = 0;
        pXmlCollisionModel->QueryIntAttribute("planeCount", &planeCount);

        pXmlPlane = pXmlCollisionModel->FirstChildElement("plane");
        for(int j = 0; j < planeCount; ++j)
        {
            Vector3f norm;
            pXmlPlane->QueryFloatAttribute("nx", &norm.x);
            pXmlPlane->QueryFloatAttribute("ny", &norm.y);
            pXmlPlane->QueryFloatAttribute("nz", &norm.z);
                float D = 0.f;
            pXmlPlane->QueryFloatAttribute("d", &D);
            Planef p(norm.z, norm.y, norm.x * -1.0f, D);
            cm->Add(p);
            pXmlPlane = pXmlPlane->NextSiblingElement("plane");
        }

        if (pGroundCollisions)
        pGroundCollisions->PushBack(cm);
        pXmlCollisionModel = pXmlCollisionModel->NextSiblingElement("collisionModel");
    }
    }
	OVR_DEBUG_LOG(("done."));
	return true;
}