void GetGraphicsCardList(OVR::Array< OVR::String > &gpus) { gpus.Clear(); char info[256] = { 0 }; FILE *file = popen("/usr/bin/lspci", "r"); if (file) { int status = 0; while (status >= 0) { status = fscanf(file, "%*[^\n]\n"); // Read up till the end of the current line, leaving the file pointer at the beginning of the next line (skipping any leading whitespace). OVR_UNUSED(status); // Prevent GCC compiler warning: "ignoring return value of ‘int fscanf(FILE*, const char*, ...)" status = fscanf(file, "%*[^ ] VGA compatible controller: %255[^\n]", info); if (status == 1) { gpus.PushBack(String(info)); } } pclose(file); } if (gpus.GetSizeI() <= 0) { gpus.PushBack(String("No video card details found.")); } }
void ovrJobManagerImpl::Shutdown() { Exiting = true; // allow all threads to complete their current job // waiting threads must timeout waiting for NewJobSignal while( Threads.GetSizeI() > 0 ) { NewJobSignal->Raise(); // raise signal to release any waiting thread // loop through threads until we find one that's seen the Exiting flag and detatched int threadIndex = 0; for ( ; ; ) { if ( Threads[threadIndex]->GetJni() == nullptr ) { LOG( "Exited thread '%s'", Threads[threadIndex]->GetThreadName() ); ovrJobThread::Destroy( Threads[threadIndex] ); Threads.RemoveAtUnordered( threadIndex ); break; } threadIndex++; if ( threadIndex >= Threads.GetSizeI() ) { threadIndex = 0; } } } ovrSignal::Destroy( NewJobSignal ); Initialized = false; }
// Called on each resume, synchronously fetches the data. void ovr_UpdateLocalPreferences() { #if defined( ENABLE_LOCAL_PREFS ) LocalPreferences.Clear(); OVR::MemBufferFile file( localPrefsFile ); // Don't bother checking for duplicate names, later ones // will be ignored and removed on write. const char * txt = (const char *)file.Buffer; LOG( "%s is length %i", localPrefsFile, file.Length ); for ( int ofs = 0 ; ofs < file.Length ; ) { KeyPair kp; int stopPos; kp.Key = ParseToken( txt, ofs, file.Length, stopPos ); ofs = stopPos; kp.Value = ParseToken( txt, ofs, file.Length, stopPos ); ofs = stopPos; if ( kp.Key.GetSize() > 0 ) { LOG( "%s = %s", kp.Key.ToCStr(), kp.Value.ToCStr() ); LocalPreferences.PushBack( kp ); } } #endif }
void VideoBrowser::OnMediaNotFound( OvrGuiSys & guiSys, String & title, String & imageFile, String & message ) { Videos.GetLocale().GetString( "@string/app_name", "@string/app_name", title ); imageFile = "assets/sdcard.png"; Videos.GetLocale().GetString( "@string/media_not_found", "@string/media_not_found", message ); OVR::Array< OVR::String > wholeStrs; wholeStrs.PushBack( "Gear VR" ); guiSys.GetDefaultFont().WordWrapText( message, 1.4f, wholeStrs ); }
OVR::GlGeometry BuildFadedScreenMask( const float xFraction, const float yFraction ) { const float posx[] = { -1.001f, -1.0f + xFraction * 0.25f, -1.0f + xFraction, 1.0f - xFraction, 1.0f - xFraction * 0.25f, 1.001f }; const float posy[] = { -1.001f, -1.0f + yFraction * 0.25f, -1.0f + yFraction, 1.0f - yFraction, 1.0f - yFraction * 0.25f, 1.001f }; const int vertexCount = 6 * 6; OVR::VertexAttribs attribs; attribs.position.Resize( vertexCount ); attribs.uv0.Resize( vertexCount ); attribs.color.Resize( vertexCount ); for ( int y = 0; y < 6; y++ ) { for ( int x = 0; x < 6; x++ ) { const int index = y * 6 + x; attribs.position[index].x = posx[x]; attribs.position[index].y = posy[y]; attribs.position[index].z = 0.0f; attribs.uv0[index].x = 0.0f; attribs.uv0[index].y = 0.0f; // the outer edges will have 0 color const float c = ( y <= 1 || y >= 4 || x <= 1 || x >= 4 ) ? 0.0f : 1.0f; for ( int i = 0; i < 3; i++ ) { attribs.color[index][i] = c; } attribs.color[index][3] = 1.0f; // solid alpha } } OVR::Array< OVR::TriangleIndex > indices; indices.Resize( 25 * 6 ); // Should we flip the triangulation on the corners? int index = 0; for ( int x = 0; x < 5; x++ ) { for ( int y = 0; y < 5; y++ ) { indices[index + 0] = y * 6 + x; indices[index + 1] = y * 6 + x + 1; indices[index + 2] = (y + 1) * 6 + x; indices[index + 3] = (y + 1) * 6 + x; indices[index + 4] = y * 6 + x + 1; indices[index + 5] = (y + 1) * 6 + x + 1; index += 6; } } return OVR::GlGeometry( attribs, indices ); }
//============================== // BitmapFontLocal::WordWrapText void BitmapFontLocal::WordWrapText( String & inOutText, const float widthMeters, OVR::Array< OVR::String > wholeStrsList, const float fontScale ) const { float const xScale = FontInfo.ScaleFactor * fontScale; const int32_t totalLength = inOutText.GetLengthI(); int32_t lastWhitespaceIndex = -1; double lineWidthAtLastWhitespace = 0.0f; double lineWidth = 0.0f; int dontSplitUntilIdx = -1; for ( int32_t pos = 0; pos < totalLength; ++pos ) { uint32_t charCode = inOutText.GetCharAt( pos ); // Replace any existing character escapes with space as we recompute where to insert line breaks if ( charCode == '\r' || charCode == '\n' || charCode == '\t' ) { inOutText.Remove( pos ); inOutText.InsertCharAt( ' ', pos ); charCode = ' '; } FontGlyphType const & g = GlyphForCharCode( charCode ); lineWidth += g.AdvanceX * xScale; for ( int i = 0; i < wholeStrsList.GetSizeI(); ++i ) { int curWholeStrLen = wholeStrsList[i].GetLengthI(); int endPos = pos + curWholeStrLen; if ( endPos < totalLength ) { String subInStr = inOutText.Substring( pos, endPos ); if ( subInStr == wholeStrsList[i] ) { dontSplitUntilIdx = Alg::Max(dontSplitUntilIdx, endPos); } } } if ( pos >= dontSplitUntilIdx ) { if ( charCode == ' ' ) { lastWhitespaceIndex = pos; lineWidthAtLastWhitespace = lineWidth; } // always check the line width and as soon as we exceed it, wrap the text at // the last whitespace. This ensure's the text always fits within the width. if ( lineWidth >= widthMeters && lastWhitespaceIndex >= 0 ) { dontSplitUntilIdx = -1; inOutText.Remove( lastWhitespaceIndex ); inOutText.InsertCharAt( '\n', lastWhitespaceIndex ); // subtract the width after the last whitespace so that we don't lose any // of the accumulated width since then. lineWidth -= lineWidthAtLastWhitespace; } } } }
void ovr_ShutdownLocalPreferences() { #if defined( ENABLE_LOCAL_PREFS ) LOG( "ovr_ShutdownLocalPreferences" ); LocalPreferences.ClearAndRelease(); #endif }
void ovrMPMCArray< T >::MoveArray( OVR::Array< T > & a ) { ovrScopedMutex mutex( ThisMutex ); for ( int i = 0; i < A.GetSizeI(); ++i ) { a.PushBack( A[i] ); } A.Clear(); }
// Updates the in-memory data and synchronously writes it to storage. void ovr_SetLocalPreferenceValueForKey( const char * keyName, const char * keyValue ) { LOG( "Set( %s, %s )", keyName, keyValue ); int i = 0; for ( ; i < LocalPreferences.GetSizeI() ; i++ ) { if ( !strcmp( keyName, LocalPreferences[i].Key.ToCStr() ) ) { LocalPreferences[i].Value = keyValue; } } if ( i == LocalPreferences.GetSizeI() ) { KeyPair kp; kp.Key = keyName; kp.Value = keyValue; LocalPreferences.PushBack( kp ); } // don't write out if prefs are disabled because we could overwrite with default values #if defined( ENABLE_LOCAL_PREFS ) // write the file FILE * f = fopen( localPrefsFile, "w" ); if ( !f ) { LOG( "Couldn't open %s for writing", localPrefsFile ); return; } for ( int i = 0 ; i < LocalPreferences.GetSizeI() ; i++ ) { fprintf( f, "%s %s", LocalPreferences[i].Key.ToCStr(), LocalPreferences[i].Value.ToCStr() ); } fclose( f ); #endif }
// Query the in-memory preferences for a key / value pair. // If the returned string is not defaultKeyValue, it will remain valid until the next ovr_UpdateLocalPreferences(). const char * ovr_GetLocalPreferenceValueForKey( const char * keyName, const char * defaultKeyValue ) { #if defined( ENABLE_LOCAL_PREFS ) for ( int i = 0 ; i < LocalPreferences.GetSizeI() ; i++ ) { if ( 0 == LocalPreferences[i].Key.CompareNoCase( keyName ) ) { LOG( "Key %s = %s", keyName, LocalPreferences[i].Value.ToCStr() ); return LocalPreferences[i].Value.ToCStr(); } } LOG( "Key %s not found, returning default %s", keyName, defaultKeyValue ); #endif return defaultKeyValue; }
void ovrJobManagerImpl::Init( JavaVM & javaVM ) { Jvm = &javaVM; // signal must be created before any job threads are created NewJobSignal = ovrSignal::Create( true ); // create all threads... they will end up waiting on a new job signal for ( int i = 0; i < MAX_THREADS; ++i ) { char threadName[16]; OVR_sprintf( threadName, sizeof( threadName ), "ovrJobThread_%i", i ); ovrJobThread * jt = ovrJobThread::Create( this, i, threadName ); Threads.PushBack( jt ); } Initialized = true; }
//todo linux, this requires searching /var/ files void GetGraphicsCardList(OVR::Array< OVR::String > &gpus) { gpus.Clear(); }
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; }