void FILEFile::init()
{
    // Open mode for file's open
    const char *omode = "rb";

    if (OpenFlags & Open_Truncate)
    {
        if (OpenFlags & Open_Read)
            omode = "w+b";
        else
            omode = "wb";
    }
    else if (OpenFlags & Open_Create)
    {
        if (OpenFlags & Open_Read)
            omode = "a+b";
        else
            omode = "ab";
    }
    else if (OpenFlags & Open_Write)
        omode = "r+b";

#ifdef OVR_OS_WIN32
    SysErrorModeDisabler disabler(FileName.ToCStr());
#endif

#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
    wchar_t womode[16];
    wchar_t *pwFileName = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(FileName.ToCStr())+1) * sizeof(wchar_t));
    UTF8Util::DecodeString(pwFileName, FileName.ToCStr());
    OVR_ASSERT(strlen(omode) < sizeof(womode)/sizeof(womode[0]));
    UTF8Util::DecodeString(womode, omode);
    _wfopen_s(&fs, pwFileName, womode);
    OVR_FREE(pwFileName);
#else
    fs = fopen(FileName.ToCStr(), omode);
#endif
    if (fs)
        rewind (fs);
    Opened = (fs != NULL);
    // Set error code
    if (!Opened)
        ErrorCode = SFerror();
    else
    {
        // If we are testing file seek correctness, pre-load the entire file so
        // that we can do comparison tests later.
#ifdef OVR_FILE_VERIFY_SEEK_ERRORS        
        TestPos         = 0;
        fseek(fs, 0, SEEK_END);
        FileTestLength  = ftell(fs);
        fseek(fs, 0, SEEK_SET);
        pFileTestBuffer = (UByte*)OVR_ALLOC(FileTestLength);
        if (pFileTestBuffer)
        {
            OVR_ASSERT(FileTestLength == (unsigned)Read(pFileTestBuffer, FileTestLength));
            Seek(0, Seek_Set);
        }        
#endif

        ErrorCode = 0;
    }
    LastOp = 0;
}
Beispiel #2
0
bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor)
{
    if (!initializeManager())
    {
        return false;
    }
    

	CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager);
    if (!deviceSet)
        return false;
    
	CFIndex deviceCount = CFSetGetCount(deviceSet);
    
    // Allocate a block of memory and read the set into it.
    IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount);
    CFSetGetValues(deviceSet, (const void **) devices);
    

    // Iterate over devices.
    for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
    {
        IOHIDDeviceRef hidDev = devices[deviceIndex];
        
        if (!hidDev)
        {
            continue;
        }
        
        HIDDeviceDesc devDesc;
                
        if (getPath(hidDev, &(devDesc.Path)) &&
            initVendorProductVersion(hidDev, &devDesc) &&
            enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId) &&
            initUsage(hidDev, &devDesc))
        {
            initStrings(hidDev, &devDesc);
            initSerialNumber(hidDev, &devDesc);

            // Look for the device to check if it is already opened.
            Ptr<DeviceCreateDesc> existingDevice = DevManager->FindHIDDevice(devDesc, true);
            // if device exists and it is opened then most likely the CreateHIDFile
            // will fail; therefore, we just set Enumerated to 'true' and continue.
            if (existingDevice && existingDevice->pDevice)
            {
                existingDevice->Enumerated = true;
                continue;
            }

            // open the device temporarily for startup communication
            if (IOHIDDeviceOpen(hidDev, kIOHIDOptionsTypeSeizeDevice) == kIOReturnSuccess)
            {
                // Construct minimal device that the visitor callback can get feature reports from.
                OSX::HIDDevice device(this, hidDev);

                enumVisitor->Visit(device, devDesc);

                IOHIDDeviceClose(hidDev, kIOHIDOptionsTypeSeizeDevice);
            }
        }
    }
    
    OVR_FREE(devices);
    CFRelease(deviceSet);
    
    return true;
}
Beispiel #3
0
bool HIDDevice::openDevice()
{
    
    // Have to iterate through devices again to generate paths.
	CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager->HIDManager);
	CFIndex deviceCount = CFSetGetCount(deviceSet);
    
    // Allocate a block of memory and read the set into it.
    IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount);
    CFSetGetValues(deviceSet, (const void **) devices);
    
    
    // Iterate over devices.
    IOHIDDeviceRef device = NULL;

    for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
    {
        IOHIDDeviceRef tmpDevice = devices[deviceIndex];
        
        if (!tmpDevice)
        {
            continue;
        }
        
        String path;
        if (!HIDManager->getPath(tmpDevice, &path))
        {
            continue;
        }
        
        if (path == DevDesc.Path)
        {
            device = tmpDevice;
            break;
        }
    }
    
    
    OVR_FREE(devices);
    
    if (!device)
    {
        CFRelease(deviceSet);
        return false;
    }
    
    // Attempt to open device.
    if (IOHIDDeviceOpen(device, kIOHIDOptionsTypeSeizeDevice)
        != kIOReturnSuccess)
    {
        CFRelease(deviceSet);
        return false;
    }

    // Retain the device before we release the set.
    CFRetain(device);
    CFRelease(deviceSet);
    
    
    Device = device;

    
    if (!initInfo())
    {
        IOHIDDeviceClose(Device, kIOHIDOptionsTypeSeizeDevice);
        CFRelease(Device);
        Device = NULL;
        return false;
    }
    
    
    // Setup the Run Loop and callbacks.
    IOHIDDeviceScheduleWithRunLoop(Device,
                                   HIDManager->getRunLoop(),
                                   kCFRunLoopDefaultMode);
    
    IOHIDDeviceRegisterInputReportCallback(Device,
                                           ReadBuffer,
                                           ReadBufferSize,
                                           staticHIDReportCallback,
                                           this);

    IOHIDDeviceRegisterRemovalCallback(Device,
                                       staticDeviceRemovedCallback,
                                       this);
    
    return 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;

    D3D1x_(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     = D3D1x_(USAGE_DEFAULT);
    dsDesc.BindFlags = D3D1x_(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 = D3D1x_(BIND_DEPTH_STENCIL);
        }
        else
        {
            dsDesc.BindFlags |= D3D1x_(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 & D3D1x_(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;
            UByte* 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 = (UByte*)OVR_ALLOC(mipw * miph * 4);
                }
                FilterRgba2x2(level == 1 ? (const UByte*)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);
            }
        }
    }
//-----------------------------------------------------------------------------
// Render an object to text.  The returned string must be freed
char* JSON::PrintObject(int depth, bool fmt)
{
	char**   entries = 0, **names = 0;
	char*    out = 0;
    char*    ptr, *ret, *str;
    intptr_t len = 7, i = 0, j;
    bool     fail = false;
	
    // Count the number of entries.
    int numentries = GetItemCount();
    
	// Explicitly handle empty object case
	if (numentries == 0)
	{
		out=(char*)OVR_ALLOC(fmt?depth+4:4);
		if (!out)
            return 0;
		ptr=out;
        *ptr++='{';
		
        if (fmt)
        {
            *ptr++='\n';
            for (i=0;i<depth-1;i++)
                *ptr++='\t';
        }
		*ptr++='}';
        *ptr++=0;
		return out;
	}
	// Allocate space for the names and the objects
	entries=(char**)OVR_ALLOC(numentries*sizeof(char*));
	if (!entries)
        return 0;
	names=(char**)OVR_ALLOC(numentries*sizeof(char*));
	
    if (!names)
    {
        OVR_FREE(entries);
        return 0;
    }
	memset(entries,0,sizeof(char*)*numentries);
	memset(names,0,sizeof(char*)*numentries);

	// Collect all the results into our arrays:
    depth++;
    if (fmt)
        len+=depth;

    JSON* child = Children.GetFirst();
    while (!Children.IsNull(child))
	{
		names[i]     = str = PrintString(child->Name);
		entries[i++] = ret = child->PrintValue(depth, fmt);

		if (str && ret)
        {
            len += OVR_strlen(ret)+OVR_strlen(str)+2+(fmt?3+depth:0);
        }
        else
        {
            fail = true;
            break;
        }
		
        child = Children.GetNext(child);
	}
	
	// Try to allocate the output string
	if (!fail)
        out=(char*)OVR_ALLOC(len);
	if (!out)
        fail=true;

	// Handle failure
	if (fail)
	{
		for (i=0;i<numentries;i++)
        {
            if (names[i])
                OVR_FREE(names[i]);
            
            if (entries[i])
                OVR_FREE(entries[i]);}
		
        OVR_FREE(names);
        OVR_FREE(entries);
		return 0;
	}
	
	// Compose the output:
	*out = '{';
    ptr  = out+1;
    if (fmt)
    {
#ifdef OVR_OS_WIN32
        *ptr++ = '\r';
#endif
        *ptr++ = '\n';
    }
    *ptr = 0;
	
    for (i=0; i<numentries; i++)
	{
		if (fmt)
        {
            for (j = 0; j < depth; j++)
            {
                *ptr++ = '\t';
            }
        }
		OVR_strcpy(ptr, len - (ptr-out), names[i]);
        ptr   += OVR_strlen(names[i]);
		*ptr++ =':';
        
        if (fmt)
        {
            *ptr++ = '\t';
        }
		
        OVR_strcpy(ptr, len - (ptr-out), entries[i]);
        ptr+=OVR_strlen(entries[i]);
		
        if (i != numentries - 1)
        {
            *ptr++ = ',';
        }
		
        if (fmt)
        {
#ifdef OVR_OS_WIN32
            *ptr++ = '\r';
#endif
            *ptr++ = '\n';
        }
        *ptr = 0;
		
        OVR_FREE(names[i]);
        OVR_FREE(entries[i]);
	}
	
	OVR_FREE(names);
    OVR_FREE(entries);
	
    if (fmt)
    {
        for (i = 0; i < depth - 1; i++)
        {
            *ptr++ = '\t';
        }
    }
	*ptr++='}';
    *ptr++=0;
	
    return out;	
}
//-----------------------------------------------------------------------------
// Render an array to text.  The returned text must be freed
char* JSON::PrintArray(int depth, bool fmt)
{
	char **  entries;
	char *   out = 0, *ptr,*ret;
    intptr_t len = 5;
	
    bool fail = false;
	
	// How many entries in the array? 
    int numentries = GetItemCount();
	if (!numentries)
	{
		out=(char*)OVR_ALLOC(3);
		if (out)
            OVR_strcpy(out, 3, "[]");
		return out;
	}
	// Allocate an array to hold the values for each
	entries=(char**)OVR_ALLOC(numentries*sizeof(char*));
	if (!entries)
        return 0;
	memset(entries,0,numentries*sizeof(char*));

	//// Retrieve all the results:
    JSON* child = Children.GetFirst();
    for (int i=0; i<numentries; i++)
	{
		//JSON* child = Children[i];
        ret=child->PrintValue(depth+1, fmt);
		entries[i]=ret;
		if (ret)
            len+=OVR_strlen(ret)+2+(fmt?1:0);
        else
        {
            fail = true;
            break;
        }
        child = Children.GetNext(child);
	}
	
	// If we didn't fail, try to malloc the output string 
	if (!fail)
        out=(char*)OVR_ALLOC(len);
	// If that fails, we fail. 
	if (!out)
        fail = true;

	// Handle failure.
	if (fail)
	{
		for (int i=0; i<numentries; i++) 
        {
            if (entries[i])
                OVR_FREE(entries[i]);
        }
		OVR_FREE(entries);
		return 0;
	}
	
	// Compose the output array.
	*out='[';
	ptr=out+1;
    *ptr=0;
	for (int i=0; i<numentries; i++)
	{
		OVR_strcpy(ptr, len - (ptr-out), entries[i]);
        ptr+=OVR_strlen(entries[i]);
		if (i!=numentries-1)
        {
            *ptr++=',';
            if (fmt)
                *ptr++=' ';
            *ptr=0;
        }
		OVR_FREE(entries[i]);
	}
	OVR_FREE(entries);
	*ptr++=']';
    *ptr++=0;
	return out;	
}
//-----------------------------------------------------------------------------
// Parses the input text into a string item and returns the text position after
// the parsed string
const char* JSON::parseString(const char* str, const char** perror)
{
	const char* ptr = str+1;
    const char* p;
    char*       ptr2;
    char*       out;
    int         len=0;
    unsigned    uc, uc2;
	
    if (*str!='\"')
    {
        return AssignError(perror, "Syntax Error: Missing quote");
    }
	
	while (*ptr!='\"' && *ptr && ++len)
    {   
        if (*ptr++ == '\\') ptr++;	// Skip escaped quotes.
    }
	
    // This is how long we need for the string, roughly.
	out=(char*)OVR_ALLOC(len+1);
	if (!out)
        return 0;
	
	ptr = str+1;
    ptr2= out;

	while (*ptr!='\"' && *ptr)
	{
		if (*ptr!='\\')
        {
            *ptr2++ = *ptr++;
        }
		else
		{
			ptr++;
			switch (*ptr)
			{
				case 'b': *ptr2++ = '\b';	break;
				case 'f': *ptr2++ = '\f';	break;
				case 'n': *ptr2++ = '\n';	break;
				case 'r': *ptr2++ = '\r';	break;
				case 't': *ptr2++ = '\t';	break;

                // Transcode utf16 to utf8.
                case 'u':

                    // Get the unicode char.
                    p = ParseHex(&uc, 4, ptr + 1);
                    if (ptr != p)
                        ptr = p - 1;

					if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)
                        break;	// Check for invalid.

                    // UTF16 surrogate pairs.
					if (uc>=0xD800 && uc<=0xDBFF)
					{
						if (ptr[1]!='\\' || ptr[2]!='u')
                            break;	// Missing second-half of surrogate.

                        p= ParseHex(&uc2, 4, ptr + 3);
                        if (ptr != p)
                            ptr = p - 1;
                        
						if (uc2<0xDC00 || uc2>0xDFFF)
                            break;	// Invalid second-half of surrogate.

						uc = 0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
					}

					len=4;
                    
                    if (uc<0x80)
                        len=1;
                    else if (uc<0x800)
                        len=2;
                    else if (uc<0x10000)
                        len=3;
                    
                    ptr2+=len;
					
					switch (len)
                    {
						case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
							//no break, fall through
						case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
							//no break
						case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
							//no break
						case 1: *--ptr2 = (char)(uc | firstByteMark[len]);
							//no break
					}
					ptr2+=len;
					break;

                default:
                    *ptr2++ = *ptr;
                    break;
			}
			ptr++;
		}
	}

	*ptr2 = 0;
	if (*ptr=='\"')
        ptr++;
	
    // Make a copy of the string 
    Value=out;
    OVR_FREE(out);
	Type=JSON_String;

	return ptr;
}
Beispiel #8
0
void DistortionMeshInit(unsigned distortionCaps, ovrHmd HMD,
                        ovrEyeRenderDesc eyeRenderDesc[2],
                        ovrSizei textureSize, ovrRecti viewports[2],
                        RenderDevice* pRender)
{
    //Generate distortion mesh for each eye
    for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
    {
        // Allocate & generate distortion mesh vertices.
        ovrDistortionMesh meshData;
        ovrHmd_CreateDistortionMesh(HMD,
                                    eyeRenderDesc[eyeNum].Eye, eyeRenderDesc[eyeNum].Fov,
                                    distortionCaps, &meshData);

        ovrHmd_GetRenderScaleAndOffset(eyeRenderDesc[eyeNum].Fov,
                                       textureSize, viewports[eyeNum],
                                       (ovrVector2f*) DistortionData.UVScaleOffset[eyeNum]);

        // Now parse the vertex data and create a render ready vertex buffer from it
        DistortionVertex * pVBVerts = (DistortionVertex*)OVR_ALLOC( 
                                       sizeof(DistortionVertex) * meshData.VertexCount );
        DistortionVertex * v        = pVBVerts;
        ovrDistortionVertex * ov    = meshData.pVertexData;
        for ( unsigned vertNum = 0; vertNum < meshData.VertexCount; vertNum++ )
        {
            v->Pos.x = ov->Pos.x;
            v->Pos.y = ov->Pos.y;
            v->TexR  = (*(Vector2f*)&ov->TexR);
            v->TexG  = (*(Vector2f*)&ov->TexG);
            v->TexB  = (*(Vector2f*)&ov->TexB);
            v->Col.R = v->Col.G = v->Col.B = (OVR::UByte)( ov->VignetteFactor * 255.99f );
            v->Col.A = (OVR::UByte)( ov->TimeWarpFactor * 255.99f );
            v++; ov++;
        }
        //Register this mesh with the renderer
        DistortionData.MeshVBs[eyeNum] = *pRender->CreateBuffer();
        DistortionData.MeshVBs[eyeNum]->Data ( Buffer_Vertex, pVBVerts,
                                               sizeof(DistortionVertex) * meshData.VertexCount );
        DistortionData.MeshIBs[eyeNum] = *pRender->CreateBuffer();
        DistortionData.MeshIBs[eyeNum]->Data ( Buffer_Index, meshData.pIndexData,
                                                sizeof(unsigned short) * meshData.IndexCount );

        OVR_FREE ( pVBVerts );
        ovrHmd_DestroyDistortionMesh( &meshData );
    }

	// Pixel shader for the mesh
	//-------------------------------------------------------------------------------------------
    const char* pixelShader =
		"Texture2D Texture   : register(t0);                                                    \n"
		"SamplerState Linear : register(s0);                                                    \n"

		"float4 main(in float4 oPosition  : SV_Position, in float4 oColor : COLOR,              \n"
		"            in float2 oTexCoord0 : TEXCOORD0,   in float2 oTexCoord1 : TEXCOORD1,      \n"
		"            in float2 oTexCoord2 : TEXCOORD2)   : SV_Target                            \n"
		"{                                                                                      \n"
		// 3 samples for fixing chromatic aberrations
		"    float ResultR = Texture.Sample(Linear, oTexCoord0.xy).r;                           \n"
		"    float ResultG = Texture.Sample(Linear, oTexCoord1.xy).g;                           \n"
		"    float ResultB = Texture.Sample(Linear, oTexCoord2.xy).b;                           \n"
		"    return float4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);    \n"
		"}";


    // Choose the vertex shader, according to if you have timewarp enabled
	if (distortionCaps & ovrDistortionCap_TimeWarp)
	{   // TIMEWARP
		//--------------------------------------------------------------------------------------------
		const char* vertexShader = 
			"float2 EyeToSourceUVScale;                                                                \n"
			"float2 EyeToSourceUVOffset;                                                               \n"
			"float4x4 EyeRotationStart;                                                             \n"
			"float4x4 EyeRotationEnd;                                                               \n"
			"float2 TimewarpTexCoord(float2 TexCoord, float4x4 rotMat)                              \n"
			"{                                                                                      \n"
			// Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic 
			// aberration and distortion). These are now "real world" vectors in direction (x,y,1) 
			// relative to the eye of the HMD.	Apply the 3x3 timewarp rotation to these vectors.
			"    float3 transformed = float3( mul ( rotMat, float4(TexCoord.xy, 1, 1) ).xyz);       \n"
			// Project them back onto the Z=1 plane of the rendered images.
			"    float2 flattened = (transformed.xy / transformed.z);                               \n"
			// Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye)
			"    return(EyeToSourceUVScale * flattened + EyeToSourceUVOffset);                             \n"
			"}                                                                                      \n"
			"void main(in float2 Position    : POSITION,    in float4 Color       : COLOR0,         \n"
			"          in float2 TexCoord0   : TEXCOORD0,   in float2 TexCoord1   : TEXCOORD1,      \n"
			"          in float2 TexCoord2   : TEXCOORD2,                                           \n"
			"          out float4 oPosition  : SV_Position, out float4 oColor     : COLOR,          \n"
			"          out float2 oTexCoord0 : TEXCOORD0,   out float2 oTexCoord1 : TEXCOORD1,      \n"
			"          out float2 oTexCoord2 : TEXCOORD2)                                           \n"
			"{                                                                                      \n"
			"    float timewarpLerpFactor = Color.a;                                                \n"
			"    float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, timewarpLerpFactor);\n"
			"    oTexCoord0  = TimewarpTexCoord(TexCoord0,lerpedEyeRot);                            \n"
			"    oTexCoord1  = TimewarpTexCoord(TexCoord1,lerpedEyeRot);                            \n"
			"    oTexCoord2  = TimewarpTexCoord(TexCoord2,lerpedEyeRot);                            \n"
			"    oPosition = float4(Position.xy, 0.5, 1.0);                                         \n"
			"    oColor = Color.r;  /*For vignette fade*/                                           \n"
			"}";
		
		pRender->InitShaders(vertexShader, pixelShader, &DistortionData.Shaders,
                             &DistortionData.VertexIL,DistortionMeshVertexDesc,5);
	}
	else
	{
		//-------------------------------------------------------------------------------------------
		const char* vertexShader = 
			"float2 EyeToSourceUVScale;                                                                \n"
			"float2 EyeToSourceUVOffset;                                                               \n"
			"void main(in float2 Position    : POSITION,    in float4 Color       : COLOR0,         \n"
			"          in float2 TexCoord0   : TEXCOORD0,   in float2 TexCoord1   : TEXCOORD1,      \n"
			"          in float2 TexCoord2   : TEXCOORD2,                                           \n"
			"          out float4 oPosition  : SV_Position, out float4 oColor     : COLOR,          \n"
			"          out float2 oTexCoord0 : TEXCOORD0,   out float2 oTexCoord1 : TEXCOORD1,      \n"
			"          out float2 oTexCoord2 : TEXCOORD2)                                           \n"
			"{                                                                                      \n"
			// Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye)
			"    oTexCoord0  = EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset;                      \n"
			"    oTexCoord1  = EyeToSourceUVScale * TexCoord1 + EyeToSourceUVOffset;                      \n"
			"    oTexCoord2  = EyeToSourceUVScale * TexCoord2 + EyeToSourceUVOffset;                      \n"
			"    oPosition = float4(Position.xy, 0.5, 1.0);                                         \n"
			"    oColor = Color.r;  /*For vignette fade*/                                           \n"
			"}";
		
		pRender->InitShaders(vertexShader, pixelShader, &DistortionData.Shaders,
                             &DistortionData.VertexIL,DistortionMeshVertexDesc,5);
	}
}