//----------------------------------------------------------------------------- // Render the number from the given item into a string. static char* PrintNumber(double d) { char *str; //double d=item->valuedouble; int valueint = (int)d; if (fabs(((double)valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) { str=(char*)OVR_ALLOC(21); // 2^64+1 can be represented in 21 chars. if (str) OVR_sprintf(str, 21, "%d", valueint); } else { str=(char*)OVR_ALLOC(64); // This is a nice tradeoff. if (str) { if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60) OVR_sprintf(str, 64, "%.0f", d); else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) OVR_sprintf(str, 64, "%e", d); else OVR_sprintf(str, 64, "%f", d); } } return str; }
//----------------------------------------------------------------------------- // Render the number from the given item into a string. static char* PrintNumber(double d) { char *str; int valueint = (int)d; if ((fabs(((double)valueint)-d) <= DBL_EPSILON) && (d <= INT_MAX) && (d >= INT_MIN)) { return PrintInt(valueint); } else { const size_t kCapacity = 64; str=(char*)OVR_ALLOC(kCapacity); // This is a nice tradeoff. if (str) { // The JSON Standard, section 7.8.3, specifies that decimals are always expressed with '.' and // not some locale-specific decimal such as ',' or ' '. However, since we are using the C standard // library below to write a floating point number, we need to make sure that it's writing a '.' // and not something else. We can't change the locale (even temporarily) here, as it will affect // the whole process by default. That are compiler-specific ways to change this per-thread, but // below we implement the simple solution of simply fixing the decimal after the string was written. if ((fabs(floor(d) - d) <= DBL_EPSILON) && (fabs(d) < 1.0e60)) { // Write integral values with no decimals OVR_sprintf(str, kCapacity, "%.0f", d); } else if ((fabs(d) < 1.0) || (fabs(d) > 1.0e9)) { // Write numbers < 1 or larger than 1e9 with 7 significant digits OVR_sprintf(str, kCapacity, "%.7g", d); } else { // Write numbers >= 1 and <= 1e9 with 6 decimals (7 to 15 sig digits) OVR_sprintf(str, kCapacity, "%.6f", d); } // Convert any found ',' or ''' char to '.'. This will happen only if the locale was set to write a ',' // instead of a '.' for the decimal point. Decimal points are represented only by one of these // three characters in practice. for(char* p = str; *p; p++) { if((*p == ',') || (*p == '\'')) { *p = '.'; break; } } } } return str; }
void MakePath( const char * dirPath, mode_t mode ) { char path[ 256 ]; char * currentChar = NULL; OVR_sprintf( path, sizeof( path ), "%s", dirPath ); for ( currentChar = path + 1; *currentChar; ++currentChar ) { if ( *currentChar == '/' ) { *currentChar = 0; DIR * checkDir = opendir( path ); if ( checkDir == NULL ) { mkdir( path, mode ); } else { closedir( checkDir ); } *currentChar = '/'; } } }
void FormatLatencyReading(char* buff, UPInt size, float val) { if (val < 0.000001f) OVR_strcpy(buff, size, "N/A "); else OVR_sprintf(buff, size, "%4.2fms", val * 1000.0f); }
static String FormatMaxFromSideTan(OptionVar* var) { char buff[64]; float degrees = 2.0f * atan(*var->AsFloat()) * (180.0f / Math<float>::Pi); OVR_sprintf(buff, sizeof(buff), "%.1f Degrees", degrees); return String(buff); }
bool SearchPaths::ToRelativePath( char const * fullPath, char * outPath, const int outMaxLen ) const { // check if the path starts with any of the search paths const int n = Paths.GetSizeI(); for ( int i = 0; i < n; ++i ) { char const * path = Paths[i].ToCStr(); if ( strstr( fullPath, path ) == fullPath ) { size_t len = OVR_strlen( path ); OVR_sprintf( outPath, outMaxLen, "%s", fullPath + len ); return true; } } OVR_sprintf( outPath, outMaxLen, "%s", fullPath ); return false; }
CFStringRef HIDDevice::generateRunLoopModeString(IOHIDDeviceRef device) { const UInt32 safeBuffSize = 256; char nameBuff[safeBuffSize]; OVR_sprintf(nameBuff, safeBuffSize, "%016lX", device); return CFStringCreateWithCString(NULL, nameBuff, kCFStringEncodingASCII); }
//----------------------------------------------------------------------------- // Render the string provided to an escaped version that can be printed. char* PrintString(const char* str) { const char *ptr; char *ptr2,*out; int len=0; unsigned char token; if (!str) return JSON_strdup(""); ptr=str; token=*ptr; while (token && ++len)\ { if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5; ptr++; token=*ptr; } int buff_size = len+3; out=(char*)OVR_ALLOC(buff_size); if (!out) return 0; ptr2 = out; ptr = str; *ptr2++ = '\"'; while (*ptr) { if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; else { *ptr2++='\\'; switch (token=*ptr++) { case '\\': *ptr2++='\\'; break; case '\"': *ptr2++='\"'; break; 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; default: OVR_sprintf(ptr2, buff_size - (ptr2-out), "u%04x",token); ptr2+=5; break; // Escape and print. } } } *ptr2++='\"'; *ptr2++=0; return out; }
// Custom formatter for Timewarp interval message. static String FormatTimewarp(OptionVar* var) { char buff[64]; float timewarpInterval = *var->AsFloat(); OVR_sprintf(buff, sizeof(buff), "%.1fms, %.1ffps", timewarpInterval * 1000.0f, ( timewarpInterval > 0.000001f ) ? 1.0f / timewarpInterval : 10000.0f); return String(buff); }
//----------------------------------------------------------------------------- // Render the number from the given item into a string. static char* PrintInt(int valueint) { char *str; str = (char*)OVR_ALLOC(21); // 2^64+1 can be represented in 21 chars. if (str) { OVR_sprintf(str, 21, "%d", valueint); } return str; }
String GetImage( eScrollBarImage const type, const bool vertical ) { static char const * images[ SCROLLBAR_IMAGE_MAX ] = { "res/raw/scrollbar_base_%s.png", "res/raw/scrollbar_thumb_%s.png", }; char buff[ 256 ]; OVR_sprintf( buff, sizeof( buff ), images[ type ], vertical ? "vert" : "horz" ); return String( buff ); }
static void AddRelativePathToHost( ovrUriScheme_File * scheme, char const * hostName, char const * baseDir, char const * relativePath ) { char rebasedPath[MAX_PATH]; OVR_sprintf( rebasedPath, sizeof( rebasedPath ), "%s/%s", baseDir, relativePath ); // collapse the path -- fopen() was not working with relative paths, though it should? char rebasedPathCanonical[MAX_PATH]; ovrPathUtils::CollapsePath( rebasedPath, rebasedPathCanonical, sizeof( rebasedPathCanonical ) ); char uri[ovrFileSysLocal::OVR_MAX_PATH_LEN]; OVR_sprintf( uri, sizeof( uri ), "file:///%s", rebasedPathCanonical ); if ( !scheme->HostExists( hostName ) ) { scheme->OpenHost( hostName, uri ); } else { scheme->AddHostSourceUri( hostName, uri); } }
bool SearchPaths::GetFullPath( char const * relativePath, char * outPath, const int outMaxLen ) const { OVR_ASSERT( outPath != NULL && outMaxLen >= 1 ); if ( FileExists( relativePath ) ) { OVR_sprintf( outPath, OVR_strlen( relativePath ) + 1, "%s", relativePath ); return true; } for ( int i = 0; i < Paths.GetSizeI(); ++i ) { OVR_sprintf( outPath, outMaxLen, "%s%s", Paths[i].ToCStr(), relativePath ); if ( FileExists( outPath ) ) { return true; // outpath is now set to the full path } } // just return the relative path if we never found the file OVR_sprintf( outPath, outMaxLen, "%s", relativePath ); return false; }
//----------------------------------------------------------------------------- // Render the number from the given item into a string. static char* PrintNumber(double d) { char *str; int valueint = (int)d; if (fabs(((double)valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) { return PrintInt(valueint); } else { str=(char*)OVR_ALLOC(64); // This is a nice tradeoff. if (str) { if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60) OVR_sprintf(str, 64, "%.0f", d); else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) OVR_sprintf(str, 64, "%e", d); else OVR_sprintf(str, 64, "%f", d); } } return str; }
void ovrSoundLimiter::PlayMenuSound( OvrGuiSys & guiSys, char const * appendKey, char const * soundName, double const limitSeconds ) { char overrideSound[ 1024 ]; OVR_sprintf( overrideSound, 1024, "%s_%s", appendKey, soundName ); if ( guiSys.GetSoundEffectPlayer().Has( overrideSound ) ) { PlaySoundEffect( guiSys, overrideSound, limitSeconds ); } else { PlaySoundEffect( guiSys, soundName, limitSeconds ); } }
String GetSliderImage( eSliderImage const type, bool vertical ) { static char const * images[SLIDER_IMAGE_MAX] = { "res/raw/slider_base_%s.png", "res/raw/slider_track_%s.png", "res/raw/slider_track_full_%s.png", "res/raw/slider_scrubber.png", "res/raw/slider_bubble_%s.png" }; char buff[256]; OVR_sprintf( buff, sizeof( buff ), images[type], vertical ? "vert" : "horz" ); return String( buff ); }
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; }
//============================== // LogEventType static inline void LogEventType( VRMenuEvent const & event, char const * fmt, ... ) { #if defined( OVR_OS_ANDROID ) if ( event.EventType != VRMENU_EVENT_TOUCH_RELATIVE ) { return; } char fmtBuff[256]; va_list args; va_start( args, fmt ); vsnprintf( fmtBuff, sizeof( fmtBuff ), fmt, args ); va_end( args ); char buffer[512]; OVR_sprintf( buffer, sizeof( buffer ), "%s: %s", VRMenuEvent::EventTypeNames[event.EventType], fmtBuff ); __android_log_write( ANDROID_LOG_WARN, "VrMenu", buffer ); #endif }
String GetSliderImage( OvrSliderComponent::imageInfo_t const & info, bool vertical ) { char buff[256]; OVR_sprintf( buff, sizeof( buff ), info.ImageName, vertical ? "vert" : "horz" ); return String( buff ); }
//============================== // OvrSliderComponent::GetStringValue void OvrSliderComponent::GetStringValue( char * valueStr, int maxLen ) const { int curValue = (int)floor( ( MaxValue - MinValue ) * SliderFrac + MinValue ); OVR_sprintf( valueStr, maxLen, "%i", curValue ); }
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; }
bool ShaderSet::Link() { glLinkProgram(Prog); GLint r; glGetProgramiv(Prog, GL_LINK_STATUS, &r); if (!r) { GLchar msg[1024]; glGetProgramInfoLog(Prog, sizeof(msg), 0, msg); OVR_DEBUG_LOG(("Linking shaders failed: %s\n", msg)); if (!r) return 0; } glUseProgram(Prog); UniformInfo.Clear(); LightingVer = 0; UsesLighting = 0; GLint uniformCount = 0; glGetProgramiv(Prog, GL_ACTIVE_UNIFORMS, &uniformCount); OVR_ASSERT(uniformCount >= 0); for(GLuint i = 0; i < (GLuint)uniformCount; i++) { GLsizei namelen; GLint size = 0; GLenum type; GLchar name[32]; glGetActiveUniform(Prog, i, sizeof(name), &namelen, &size, &type, name); if (size) { int l = glGetUniformLocation(Prog, name); char *np = name; while (*np) { if (*np == '[') *np = 0; np++; } Uniform u; u.Name = name; u.Location = l; u.Size = size; switch (type) { case GL_FLOAT: u.Type = 1; break; case GL_FLOAT_VEC2: u.Type = 2; break; case GL_FLOAT_VEC3: u.Type = 3; break; case GL_FLOAT_VEC4: u.Type = 4; break; case GL_FLOAT_MAT3: u.Type = 12; break; case GL_FLOAT_MAT4: u.Type = 16; break; default: continue; } UniformInfo.PushBack(u); if (!strcmp(name, "LightCount")) UsesLighting = 1; } else break; } ProjLoc = glGetUniformLocation(Prog, "Proj"); ViewLoc = glGetUniformLocation(Prog, "View"); for (int i = 0; i < 8; i++) { char texv[32]; OVR_sprintf(texv, 10, "Texture%d", i); TexLoc[i] = glGetUniformLocation(Prog, texv); if (TexLoc[i] < 0) break; glUniform1i(TexLoc[i], i); } if (UsesLighting) OVR_ASSERT(ProjLoc >= 0 && ViewLoc >= 0); return 1; }
String OptionVar::FormatInt(OptionVar* var) { char buff[64]; OVR_sprintf(buff, sizeof(buff), var->FormatString, *var->AsInt()); return String(buff); }
static int discoverExtendedRifts(OVR::DisplayDesc* descriptorArray, int inputArraySize, bool /*edidInfo*/) { int result = 0; if (X11Display == NULL) { OVR::LogError("[Linux Display] Unable to open X Display!"); return 0; } Atom EDIDAtom = XInternAtom(X11Display, RR_PROPERTY_RANDR_EDID, False); int numScreens = XScreenCount(X11Display); for (int i = 0; i < numScreens; ++i) { Window sr = XRootWindow(X11Display, i); XRRScreenResources* screen = XRRGetScreenResources(X11Display, sr); for (int ii = 0; ii < screen->ncrtc; ++ii) { XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(X11Display, screen, screen->crtcs[ii]); if (0 == crtcInfo->noutput) { XRRFreeCrtcInfo(crtcInfo); continue; } bool foundOutput = false; RROutput output = crtcInfo->outputs[0]; for (int k = 0; k < crtcInfo->noutput; ++k) { XRROutputInfo* outputInfo = XRRGetOutputInfo(X11Display, screen, crtcInfo->outputs[k]); for (int kk = 0; kk < outputInfo->nmode; ++kk) { if (outputInfo->modes[kk] == crtcInfo->mode) { output = crtcInfo->outputs[k]; foundOutput = true; break; } } XRRFreeOutputInfo(outputInfo); if (foundOutput) { break; } } if (!foundOutput) { XRRFreeCrtcInfo(crtcInfo); continue; } XRROutputInfo* outputInfo = XRRGetOutputInfo(X11Display, screen, output); if (RR_Connected != outputInfo->connection) { XRRFreeOutputInfo(outputInfo); XRRFreeCrtcInfo(crtcInfo); continue; } // Read EDID associated with crtc. uint8_t* data = NULL; int dataLen = 0; if (getXRRProperty(X11Display, output, EDIDAtom, &data, &dataLen) != 0) { // Identify rifts based on EDID. Linux::DisplayEDID edid; parseEdid(data, edid); XFree(data); data = NULL; // TODO: Remove either this 3rdParty call to read EDID data // or remove our own parsing of the EDID. Probably opt // to remove our parsing. MonitorInfo* mi = read_edid_data(X11Display, output); if (mi == NULL) { XRRFreeOutputInfo(outputInfo); XRRFreeCrtcInfo(crtcInfo); continue; } if (edid.VendorName == "OVR") { if( result >= inputArraySize ) { delete mi; XRRFreeOutputInfo(outputInfo); XRRFreeCrtcInfo(crtcInfo); return result; } XRRModeInfo* modeInfo = findModeByXID(screen, crtcInfo->mode); int width = modeInfo->width; int height = modeInfo->height; int x = crtcInfo->x; int y = crtcInfo->y; // Generate a device ID string similar Windows does it char device_id[32]; OVR_sprintf(device_id, 32, "%s%04d-%d", mi->manufacturer_code, mi->product_code, screen->crtcs[ii]); OVR::DisplayDesc& desc = descriptorArray[result++]; desc.ResolutionInPixels = Sizei(width, height); desc.DesktopDisplayOffset = Vector2i(x, y); strncpy(desc.DisplayID, device_id, sizeof(desc.DisplayID)-1); desc.DisplayID[sizeof(desc.DisplayID)-1] = 0; strncpy(desc.ModelName, edid.MonitorName, sizeof(desc.ModelName)-1); desc.ModelName[sizeof(desc.ModelName)-1] = 0; strncpy(desc.EdidSerialNumber, edid.SerialNumber, sizeof(desc.EdidSerialNumber)-1); desc.EdidSerialNumber[sizeof(desc.EdidSerialNumber)-1] = 0; bool tallScreen = (height > width); switch (crtcInfo->rotation) { default: desc.Rotation = tallScreen ? 270 : 0; break; case RR_Rotate_90: desc.Rotation = tallScreen ? 0 : 90; break; case RR_Rotate_180: desc.Rotation = tallScreen ? 90 : 180; break; case RR_Rotate_270: desc.Rotation = tallScreen ? 180 : 270; break; } switch (mi->product_code) { case 3: desc.DeviceTypeGuess = HmdType_DK2; break; case 2: desc.DeviceTypeGuess = HmdType_DKHDProto; break; case 1: desc.DeviceTypeGuess = HmdType_DK1; break; default: case 0: desc.DeviceTypeGuess = HmdType_Unknown; break; } // Hard-coded defaults in case the device doesn't have the // data itself. DK2 prototypes (0003) or DK HD Prototypes (0002). if ( desc.DeviceTypeGuess == HmdType_DK2 || desc.DeviceTypeGuess == HmdType_DKHDProto) { desc.ResolutionInPixels = Sizei(1920, 1080); } else { desc.ResolutionInPixels = Sizei(width, height); } } delete mi; mi = NULL; } else { XFree(data); } XRRFreeOutputInfo(outputInfo); XRRFreeCrtcInfo(crtcInfo); } XRRFreeScreenResources(screen); } return result; }
//============================== // ovrFileSysLocal::ovrFileSysLocal ovrFileSysLocal::ovrFileSysLocal( ovrJava const & javaContext ) { // always do unit tests on startup to assure nothing has been broken ovrUri::DoUnitTest(); #if defined( OVR_OS_ANDROID ) // add the apk scheme ovrUriScheme_Apk * scheme = new ovrUriScheme_Apk( "apk" ); // add a host for the executing application's scheme char curPackageName[OVR_MAX_PATH_LEN]; ovr_GetCurrentPackageName( javaContext.Env, javaContext.ActivityObject, curPackageName, sizeof( curPackageName ) ); char curPackageCodePath[OVR_MAX_PATH_LEN]; ovr_GetPackageCodePath( javaContext.Env, javaContext.ActivityObject, curPackageCodePath, sizeof( curPackageCodePath ) ); // not sure if this is necessary... shouldn't the application always have permission to open its own scheme? /* String outPath; const bool validCacheDir = StoragePaths->GetPathIfValidPermission( EST_INTERNAL_STORAGE, EFT_CACHE, "", permissionFlags_t( PERMISSION_WRITE ) | PERMISSION_READ, outPath ); ovr_OpenApplicationPackage( temp, validCacheDir ? outPath.ToCStr() : NULL ); */ char curPackageUri[OVR_MAX_URI_LEN]; OVR_sprintf( curPackageUri, sizeof( curPackageUri ), "file://%s", curPackageCodePath ); if ( !scheme->OpenHost( "localhost", curPackageUri ) ) { LOG( "Failed to OpenHost for host '%s', uri '%s'", "localhost", curPackageUri ); OVR_ASSERT( false ); } // add the hosts for the system activities apk /// FIXME: why do we try to add the PUI_PACKAGE_NAME package and then curPackageName? Shouldn't /// the PUI_PACKAGE_NAME (i.e. System Activities) always exist and shouldn't we always add /// the current package as a valid host name anyway? // NOTE: we do not add a "com.<company>.<appname>" ( i.e. the Android app's package name ) host // for Windows because we don't really have a good way of knowing what the Android package name // on Windows without parsing the AndroidManifest.xml explicitly for that reason. This means // using apk://com.<company>.<appname> for the scheme and host will fail on non-Android builds. // This, in turn, means that any access to the apps own assets should just be done with // apk://localhost/ in order to be cross-platform compatible. Because of that, we do not add // "com.<company>.<appname>" as a host on Android, either (since it would just fail on Windows). { for ( int i = 0; i < 2; ++i ) { char const * packageName = ( i == 0 ) ? PUI_PACKAGE_NAME : curPackageName; char packagePath[OVR_MAX_PATH_LEN]; packagePath[0] = '\0'; if ( ovr_GetInstalledPackagePath( javaContext.Env, javaContext.ActivityObject, packageName, packagePath, sizeof( packagePath ) ) ) { char packageUri[sizeof( packagePath ) + 7 ]; OVR_sprintf( packageUri, sizeof( packageUri ), "file://%s", packagePath ); scheme->OpenHost( packageName, packageUri ); break; } } } Schemes.PushBack( scheme ); // add the host for font assets by opening a stream and trying to load res/raw/font_location.txt from the System Activites apk. // If this file exists then { MemBufferT< uint8_t > buffer; char fileName[256]; OVR::OVR_sprintf( fileName, sizeof( fileName ), "apk://%s/res/raw/font_location.txt", PUI_PACKAGE_NAME ); char fontPackageName[1024]; bool success = ReadFile( fileName, buffer ); if ( success && buffer.GetSize() > 0 ) { OVR::OVR_strncpy( fontPackageName, sizeof( fontPackageName ), ( char const * )( static_cast< uint8_t const * >( buffer ) ), buffer.GetSize() ); LOG( "Found font package name '%s'", fontPackageName ); } else { // default to the SystemActivities apk. OVR::OVR_strcpy( fontPackageName, sizeof( fontPackageName ), PUI_PACKAGE_NAME ); } char packagePath[OVR_MAX_PATH_LEN]; packagePath[0] = '\0'; if ( ovr_GetInstalledPackagePath( javaContext.Env, javaContext.ActivityObject, fontPackageName, packagePath, sizeof( packagePath ) ) ) { // add this package to our scheme as a host so that fonts can be loaded from it char packageUri[sizeof( packagePath ) + 7 ]; OVR_sprintf( packageUri, sizeof( packageUri ), "file://%s", packagePath ); // add the package name as an explict host if it doesn't already exists -- it will already exist if the package name // is not overrloaded by font_location.txt (i.e. the fontPackageName will have defaulted to PUI_PACKAGE_NAME ) if ( !scheme->HostExists( fontPackageName ) ) { scheme->OpenHost( fontPackageName, packageUri ); } scheme->OpenHost( "font", packageUri ); LOG( "Added host '%s' for fonts @'%s'", fontPackageName, packageUri ); } } #elif defined( OVR_OS_WIN32 ) ovrPathUtils::DoUnitTests(); // Assume the working dir has an assets/ and res/ folder in it as is common on Android. Normally // the working folder would be Projects/Android. char curWorkingDir[MAX_PATH]; _getcwd( curWorkingDir, sizeof( curWorkingDir ) ); char uriWorkingDir[MAX_PATH]; ovrPathUtils::FixSlashesForUri( curWorkingDir, uriWorkingDir, sizeof( uriWorkingDir ) ); // if the asset package exists in the current working dir, add it as an apk scheme instead of using // raw files const char * const PACKAGE_EXTENSION = "pak"; char packagePath[MAX_PATH]; OVR_sprintf( packagePath, sizeof( packagePath ), "%s\\%s.%s", curWorkingDir, "assets", PACKAGE_EXTENSION ); if ( _access( packagePath, 04 ) == 0 ) { // package exists ovrUriScheme_Apk * scheme = new ovrUriScheme_Apk( "apk" ); char packageUri[OVR_MAX_URI_LEN]; OVR_sprintf( packageUri, sizeof( packageUri ), "file://%s", packagePath ); ovrPathUtils::FixSlashesForUriInPlace( packageUri ); if ( !scheme->OpenHost( "localhost", packageUri ) ) { LOG( "Failed to OpenHost for host '%s', uri '%s'", "localhost", packageUri ); OVR_ASSERT( false ); } // NOTE: we do not add a "com.<company>.<appname>" ( i.e. the Android app's package name ) host // for Windows because we don't really have a good way of knowing what the Android package name // on Windows without parsing the AndroidManifest.xml explicitly for that reason. This means // using apk://com.<company>.<appname> for the scheme and host will fail on non-Android builds. // This, in turn, means that any access to the apps own assets should just be done with // apk://localhost/ in order to be cross-platform compatible. Because of that, we do not add // "com.<company>.<appname>" as a host on Android, either (since it would just fail on Windows). // Currently "com.oculus.systemactivities" and "font" hosts assume the SA assets are simply // packed into the application's asset package. if ( !scheme->OpenHost( PUI_PACKAGE_NAME, packageUri ) ) { LOG( "Failed to OpenHost for host '%s', uri '%s'", PUI_PACKAGE_NAME, packageUri ); OVR_ASSERT( false ); } if ( !scheme->OpenHost( "font", packageUri ) ) { LOG( "Failed to OpenHost for host '%s', uri '%s'", "font", packageUri ); OVR_ASSERT( false ); } Schemes.PushBack(scheme); } else { // add the apk scheme for the working path ovrUriScheme_File * scheme = new ovrUriScheme_File("apk"); // On Android we have several different APK hosts: // - apk://com.oculus.systemactivities/ : this may hold vrapi.so, font_location.txt, or font data. // - apk://font/ : this may hold font data, if font data has been moved out of SystemActivities apk, // so all fonts should be loaded via this host. // - apk://localhost/ : the default host that maps to the application's own apk. char dataUri[OVR_MAX_PATH_LEN]; OVR_sprintf( dataUri, sizeof( dataUri ), "file:///%s", uriWorkingDir ); // HACK: this is currently relying on the relative path to VrAppFramework being the same for all projects, which it's not. // FIXME: change this to use command line parameters that specify additional paths. AddRelativePathToHost( scheme, "localhost", curWorkingDir, "../../../VrAppFramework" ); AddRelativePathToHost( scheme, "localhost", curWorkingDir, "../../../VrAppSupport/VrGUI" ); AddRelativePathToHost( scheme, "localhost", curWorkingDir, "../../../VrAppSupport/Net" ); AddRelativePathToHost( scheme, "localhost", curWorkingDir, "../Libraries/ovr_sdks/ovr_sdk_mobile/VrAppFramework" ); AddRelativePathToHost( scheme, "localhost", curWorkingDir, "../Libraries/ovr_sdks/ovr_sdk_mobile/VrAppSupport/VrGUI" ); AddRelativePathToHost( scheme, "localhost", curWorkingDir, "../Libraries/AppSupport/Net" ); scheme->AddHostSourceUri( "localhost", dataUri ); AddRelativePathToHost( scheme, PUI_PACKAGE_NAME, curWorkingDir, "../../../VrAppFramework" ); AddRelativePathToHost( scheme, PUI_PACKAGE_NAME, curWorkingDir, "../../../VrAppSupport/VrGUI" ); // MA: This path works if target is within Projects AddRelativePathToHost( scheme, PUI_PACKAGE_NAME, curWorkingDir, "../../../../../../VrAppFramework" ); AddRelativePathToHost( scheme, PUI_PACKAGE_NAME, curWorkingDir, "../../../../../../VrAppSupport/VrGUI" ); AddRelativePathToHost( scheme, PUI_PACKAGE_NAME, curWorkingDir, "../Libraries/ovr_sdks/ovr_sdk_mobile/VrAppFramework" ); AddRelativePathToHost( scheme, PUI_PACKAGE_NAME, curWorkingDir, "../Libraries/ovr_sdks/ovr_sdk_mobile/VrAppSupport/VrGUI" ); scheme->AddHostSourceUri( PUI_PACKAGE_NAME, dataUri ); AddRelativePathToHost( scheme, "font", curWorkingDir, "../../../VrAppFramework" ); AddRelativePathToHost( scheme, "font", curWorkingDir, "../../../VrAppSupport/VrGUI" ); // MA: This path works if target is within Projects AddRelativePathToHost( scheme, "font", curWorkingDir, "../../../../../../VrAppFramework"); AddRelativePathToHost( scheme, "font", curWorkingDir, "../../../../../../VrAppSupport/VrGUI"); AddRelativePathToHost( scheme, "font", curWorkingDir, "../Libraries/ovr_sdks/ovr_sdk_mobile/VrAppFramework" ); AddRelativePathToHost( scheme, "font", curWorkingDir, "../Libraries/ovr_sdks/ovr_sdk_mobile/VrAppSupport/VrGUI" ); scheme->AddHostSourceUri( "font", dataUri ); Schemes.PushBack( scheme ); } #else #error Unsupported platform! #endif }
void OculusWorldDemoApp::RenderTextInfoHud(float textHeight) { // View port & 2D ortho projection must be set before call. float hmdYaw, hmdPitch, hmdRoll; switch(TextScreen) { case Text_Info: { char buf[512], gpustat[256]; // Average FOVs. FovPort leftFov = EyeRenderDesc[0].Fov; FovPort rightFov = EyeRenderDesc[1].Fov; // Rendered size changes based on selected options & dynamic rendering. int pixelSizeWidth = EyeTexture[0].Header.RenderViewport.Size.w + ((!ForceZeroIpd) ? EyeTexture[1].Header.RenderViewport.Size.w : 0); int pixelSizeHeight = ( EyeTexture[0].Header.RenderViewport.Size.h + EyeTexture[1].Header.RenderViewport.Size.h ) / 2; // No DK2, no message. char latency2Text[128] = ""; { //float latency2 = ovrHmd_GetMeasuredLatencyTest2(Hmd) * 1000.0f; // show it in ms //if (latency2 > 0) // OVR_sprintf(latency2Text, sizeof(latency2Text), "%.2fms", latency2); float latencies[3] = { 0.0f, 0.0f, 0.0f }; if (ovrHmd_GetFloatArray(Hmd, "DK2Latency", latencies, 3) == 3) { char latencyText0[32], latencyText1[32], latencyText2[32]; FormatLatencyReading(latencyText0, sizeof(latencyText0), latencies[0]); FormatLatencyReading(latencyText1, sizeof(latencyText1), latencies[1]); FormatLatencyReading(latencyText2, sizeof(latencyText2), latencies[2]); OVR_sprintf(latency2Text, sizeof(latency2Text), " DK2 Latency Ren: %s TWrp: %s\n" " PostPresent: %s ", latencyText0, latencyText1, latencyText2); } } ThePlayer.HeadPose.Rotation.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&hmdYaw, &hmdPitch, &hmdRoll); OVR_sprintf(buf, sizeof(buf), " HMD YPR:%4.0f %4.0f %4.0f Player Yaw: %4.0f\n" " FPS: %.1f ms/frame: %.1f Frame: %d\n" " Pos: %3.2f, %3.2f, %3.2f HMD: %s\n" " EyeHeight: %3.2f, IPD: %3.1fmm\n" //", Lens: %s\n" " FOV %3.1fx%3.1f, Resolution: %ix%i\n" "%s", RadToDegree(hmdYaw), RadToDegree(hmdPitch), RadToDegree(hmdRoll), RadToDegree(ThePlayer.BodyYaw.Get()), FPS, SecondsPerFrame * 1000.0f, FrameCounter, ThePlayer.BodyPos.x, ThePlayer.BodyPos.y, ThePlayer.BodyPos.z, //GetDebugNameHmdType ( TheHmdRenderInfo.HmdType ), HmdDesc.ProductName, ThePlayer.UserEyeHeight, ovrHmd_GetFloat(Hmd, OVR_KEY_IPD, 0) * 1000.0f, //( EyeOffsetFromNoseLeft + EyeOffsetFromNoseRight ) * 1000.0f, //GetDebugNameEyeCupType ( TheHmdRenderInfo.EyeCups ), // Lens/EyeCup not exposed (leftFov.GetHorizontalFovDegrees() + rightFov.GetHorizontalFovDegrees()) * 0.5f, (leftFov.GetVerticalFovDegrees() + rightFov.GetVerticalFovDegrees()) * 0.5f, pixelSizeWidth, pixelSizeHeight, latency2Text ); size_t texMemInMB = pRender->GetTotalTextureMemoryUsage() / 1058576; if (texMemInMB) { OVR_sprintf(gpustat, sizeof(gpustat), " GPU Tex: %u MB", texMemInMB); OVR_strcat(buf, sizeof(buf), gpustat); } DrawTextBox(pRender, 0.0f, 0.0f, textHeight, buf, DrawText_Center); } break; case Text_Timing: Profiler.DrawOverlay(pRender); break; case Text_Help1: DrawTextBox(pRender, 0.0f, 0.0f, textHeight, HelpText1, DrawText_Center); break; case Text_Help2: DrawTextBox(pRender, 0.0f, 0.0f, textHeight, HelpText2, DrawText_Center); break; case Text_None: break; default: OVR_ASSERT ( !"Missing text screen" ); break; } }
String OptionVar::FormatFloat(OptionVar* var) { char buff[64]; OVR_sprintf(buff, sizeof(buff), var->FormatString, *var->AsFloat() * var->FormatScale); return String(buff); }