예제 #1
0
intptr_t DefaultAssertionHandler(intptr_t /*userParameter*/, const char* title, const char* message)
{
    if(OVRIsDebuggerPresent())
    {
        OVR_DEBUG_BREAK;
    }
    else
    {
        #if defined(OVR_BUILD_DEBUG)
            // Print a stack trace of all threads.
            OVR::String s;
            OVR::String threadListOutput;
            static OVR::SymbolLookup symbolLookup;

            s = "Failure: "; 
            s += message;

            if(symbolLookup.Initialize() && symbolLookup.ReportThreadCallstack(threadListOutput, 4)) // This '4' is there to skip our internal handling and retrieve starting at the assertion location (our caller) only.
            {
                s += "\r\n\r\n";
                s += threadListOutput;
            }

            OVR::Util::DisplayMessageBox(title, s.ToCStr());
        #else
            OVR::Util::DisplayMessageBox(title, message);
        #endif
    }
    
    return 0;
}
예제 #2
0
intptr_t DefaultAssertionHandler(intptr_t /*userParameter*/, const char* title, const char* message)
{
    if(OVRIsDebuggerPresent())
    {
        OVR_DEBUG_BREAK;
    }
    else
    {
        OVR_UNUSED(title);
        OVR_UNUSED(message);

        #if defined(OVR_BUILD_DEBUG)
            if(Allocator::GetInstance()) // The code below currently depends on having a valid Allocator.
            {
                // Print a stack trace of all threads.
                OVR::String s;
                OVR::String threadListOutput;
                static OVR::SymbolLookup symbolLookup;

                s = "Failure: ";
                s += message;

                if(symbolLookup.Initialize() && symbolLookup.ReportThreadCallstack(threadListOutput, 4)) // This '4' is there to skip our internal handling and retrieve starting at the assertion location (our caller) only.
                {
                    // threadListOutput has newlines that are merely \n, whereas Windows MessageBox wants \r\n newlines. So we insert \r in front of all \n.
                    for(size_t i = 0, iEnd = threadListOutput.GetSize(); i < iEnd; i++)
                    {
                        if(threadListOutput[i] == '\n')
                        {
                            threadListOutput.Insert("\r", i, 1);
                            ++i;
                            ++iEnd;
                        }
                    }

                    s += "\r\n\r\n";
                    s += threadListOutput;
                }

                OVR::Util::DisplayMessageBox(title, s.ToCStr());
            }
            else
            {
                OVR::Util::DisplayMessageBox(title, message);
            }
        #else
            OVR::Util::DisplayMessageBox(title, message);
        #endif
    }

    return 0;
}
예제 #3
0
bool CoreTexture::RebuildTexture(JSContext* cx, OVR::String pathStr) {
  OVR::FreeTexture(texture);

  if (pathStr.IsEmpty()) {
    return true;
  }

  OVR::MemBufferFile bufferFile(OVR::MemBufferFile::NoInit);

  if (CURRENT_BASE_DIR.IsEmpty()) {
    if (!OVR::ovr_ReadFileFromApplicationPackage(pathStr.ToCStr(), bufferFile)) {
      JS_ReportError(cx, "Could not read texture from application package");
      return false;
    }
  } else {
    OVR::String fullFileStr = FullFilePath(pathStr);
    if (!bufferFile.LoadFile(fullFileStr.ToCStr())) {
      JS_ReportError(cx, "Could not read texture %s", fullFileStr.ToCStr());
      return false;
    }
  }

  // Now load it
  texture = OVR::LoadTextureFromBuffer(
    pathStr.ToCStr(),
    bufferFile,
    OVR::TextureFlags_t(OVR::TEXTUREFLAG_NO_DEFAULT), // TODO: Make configurable
    width,
    height
  );

  BuildTextureMipmaps(texture); // Optional? Also does this happen in LoadTextureFromBuffer?

  // TODO: MakeTextureClamped MakeTextureLodClamped MakeTextureTrilinear
  //       MakeTextureLinear, MakeTextureAniso

  return true;
}
예제 #4
0
bool GetSysErrorCodeString(ovrSysErrorCode sysErrorCode, bool prefixErrorCode, OVR::String& sResult)
{
    char errorBuffer[1024];
    errorBuffer[0] = '\0';

    if (prefixErrorCode)
    {
        char prefixBuffer[64];
        snprintf(prefixBuffer, OVR_ARRAY_COUNT(prefixBuffer), "0x%llx (%lld): ", (uint64_t)sysErrorCode, (int64_t)sysErrorCode);
        sResult = prefixBuffer;
    }
    else
    {
        sResult.Clear();
    }

    #if defined(OVR_OS_WIN32)
        // Note: It may be useful to use FORMAT_MESSAGE_FROM_HMODULE here to get a module-specific error string if our source of errors
        // ends up including more than just system-native errors. For example, a third party module with custom errors defined in it.

        WCHAR errorBufferW[1024];
        DWORD errorBufferWCapacity = OVR_ARRAY_COUNT(errorBufferW);
        DWORD length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, (DWORD)sysErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errorBufferW, errorBufferWCapacity, nullptr);

        if (!length) // If failed...
        {
            if (HRESULT_FACILITY(sysErrorCode) == _FACDXGI) // If it is a DXGI error...
            {
                // This situation occurs on Windows 7. You can't use FORMAT_MESSAGE_FROM_HMODULE to solve it either. We can only use DXGetErrorString or manually handle it.
                const wchar_t* pStr = OVR_DXGetErrorStringW(sysErrorCode);

                if (pStr)
                {
                    wcscpy_s(errorBufferW, OVR_ARRAY_COUNT(errorBufferW), pStr);
                    length = (DWORD)wcslen(errorBufferW);
                }
            }
        }

        if (length) // If errorBufferW contains what we are looking for...
        {
            // Need to convert WCHAR errorBuffer to UTF8 char sResult;
            const auto requiredUTF8Length = OVR::UTF8Util::Strlcpy(errorBuffer, OVR_ARRAY_COUNT(errorBuffer), errorBufferW);
            if (requiredUTF8Length >= OVR_ARRAY_COUNT(errorBuffer)) // Zero out if too big (XXX truncate instead?)
                errorBuffer[0] = '\0';
            // Else fall through
        } // Else fall through
    #else
        #if (((_POSIX_C_SOURCE >= 200112L) || (_XOPEN_SOURCE >= 600)) && !_GNU_SOURCE) || defined(__APPLE__) || defined(__BSD__)
            const int result = strerror_r((int)sysErrorCode, errorBuffer, OVR_ARRAY_COUNT(errorBuffer));

            if (result != 0)        // If failed... [result is 0 upon success; result will be EINVAL if the code is not recognized; ERANGE if buffer didn't have enough capacity.]
                errorBuffer[0] = '\0';  // re-null-terminate, in case strerror_r left it in an invalid state.
        #else
            const char* result = strerror_r((int)sysErrorCode, errorBuffer, OVR_ARRAY_COUNT(errorBuffer));

            if (result == nullptr)  // Implementations in practice seem to always return a pointer, though the behavior isn't formally standardized.
                errorBuffer[0] = '\0';  // re-null-terminate, in case strerror_r left it in an invalid state.
        #endif
    #endif

    // Fall through functionality of simply printing the value as an integer.
    if (errorBuffer[0]) // If errorBuffer was successfully written above...
    {
        sResult += errorBuffer;
        return true;
    }

    sResult += "(unknown)"; // This is not localized. Question: Is there a way to get the error formatting functions above to print this themselves in a localized way?
    return false;
}
예제 #5
0
String OVRError::GetErrorString() const
{
    StringBuffer stringBuffer("OVR Error:\n");

    // Code
    OVR::String errorCodeString;
    GetErrorCodeString(Code, false, errorCodeString);
    stringBuffer.AppendFormat("  Code: %d -- %s\n", Code, errorCodeString.ToCStr());

    // SysCode
    if (SysCode != ovrSysErrorCodeSuccess)
    {
        OVR::String sysErrorString;
        GetSysErrorCodeString(SysCode, false, sysErrorString);
        OVRRemoveTrailingNewlines(sysErrorString);
        stringBuffer.AppendFormat("  System error: %d (%x) -- %s\n", (int)SysCode, (int)SysCode, sysErrorString.ToCStr());
    }

    // Description
    if (Description.GetLength())
    {
        stringBuffer.AppendFormat("  Description: %s\n", Description.ToCStr());
    }

    // OVRTime
    stringBuffer.AppendFormat("  OVRTime: %f\n", OVRTime);

    // SysClockTime
    OVR::String sysClockTimeString;
    OVRFormatDateTime(ClockTime, sysClockTimeString);
    stringBuffer.AppendFormat("  Time: %s\n", sysClockTimeString.ToCStr());

    // Context
    if (Context.GetLength())
    {
        stringBuffer.AppendFormat("  Context: %s\n", Context.ToCStr());
    }

    // If LogLine is set,
    if (LogLine != kLogLineUnset)
    {
        stringBuffer.AppendFormat("  LogLine: %lld\n", LogLine);
    }

    // FILE/LINE
    if (SourceFilePath.GetLength())
    {
        stringBuffer.AppendFormat("  File/Line: %s:%d\n", SourceFilePath.ToCStr(), SourceFileLine);
    }

    // Backtrace
    if (Backtrace.GetSize())
    {
        // We can trace symbols in a debug build here or we can trace just addresses. See other code for
        // examples of how to trace symbols.
        stringBuffer.AppendFormat("  Backtrace: ");
        for (size_t i = 0, iEnd = Backtrace.GetSize(); i != iEnd; ++i)
            stringBuffer.AppendFormat(" %p", Backtrace[i]);
        stringBuffer.AppendChar('\n');
    }

    return OVR::String(stringBuffer.ToCStr(), stringBuffer.GetSize());
}
예제 #6
0
bool CoreTexture::RebuildCubemap(JSContext* cx, OVR::String pathStr) {
  OVR::FreeTexture(texture);

  if (pathStr.IsEmpty()) {
    return true;
  }

  // Get the file extension, and a copy of the path with no extension
  OVR::String ext = pathStr.GetExtension();
  OVR::String noExt(pathStr);
  noExt.StripExtension();

  // Create some membuffers for the files we're going to open
  OVR::MemBufferFile mbfs[6] = { 
    OVR::MemBufferFile(OVR::MemBufferFile::NoInit), 
    OVR::MemBufferFile(OVR::MemBufferFile::NoInit),
    OVR::MemBufferFile(OVR::MemBufferFile::NoInit),
    OVR::MemBufferFile(OVR::MemBufferFile::NoInit),
    OVR::MemBufferFile(OVR::MemBufferFile::NoInit),
    OVR::MemBufferFile(OVR::MemBufferFile::NoInit) 
  };
  
  // Load all of them up
  const char* const cubeSuffix[6] = {"_px", "_nx", "_py", "_ny", "_pz", "_nz"};
  for (int side = 0; side < 6; ++side) {
    OVR::String sidePath = noExt + OVR::String(cubeSuffix[side]) + ext;
    if (CURRENT_BASE_DIR.IsEmpty()) {
      if (!OVR::ovr_ReadFileFromApplicationPackage(sidePath.ToCStr(), mbfs[side])) {
        JS_ReportError(cx, "Could not load cube file");
        return false;
      }
    } else {
      OVR::String fullFileStr = FullFilePath(sidePath);
      if (!mbfs[side].LoadFile(fullFileStr.ToCStr())) {
        JS_ReportError(cx, "Could not load cube file");
        return false;
      }
    }
    
    
  }

  unsigned char* data[6];
  int comp, imgWidth, imgHeight;
  // For each side of the cube
  for (int i = 0; i < 6; ++i) {
    // Load the image
    data[i] = (unsigned char *)stbi_load_from_memory(
      (unsigned char *)mbfs[i].Buffer, mbfs[i].Length, &imgWidth, &imgHeight, &comp, 4);

    // Sanity check image dimensions
    if (imgWidth != width) {
      JS_ReportError(cx, "Cubemap has mismatched image width");
      return false;
    }
    if (imgHeight != height) {
      JS_ReportError(cx, "Cubemap has mismatched image height");
      return false;
    }
    if (imgWidth <= 0 || imgWidth > 32768 || imgHeight <= 0 || imgHeight > 32768) {
      JS_ReportError(cx, "Invalid texture size");
      return false;
    }
  }

  GLenum glFormat;
  GLenum glInternalFormat;
  if (!TextureFormatToGlFormat(OVR::Texture_RGBA, true, glFormat, glInternalFormat)) {
    JS_ReportError(cx, "Invalid texture format OVR::Texture_RGBA");
    return false;
  }

  GLuint texId;
  glGenTextures(1, &texId);
  glBindTexture(GL_TEXTURE_CUBE_MAP, texId);

  // Get the total size (GetOvrTextureSize(OVR::Texture_RGBA, width, height) * 6)
  // size_t totalSize = (((width + 3) / 4) * ((height + 3) / 4) * 8) * 6;

  for (int i = 0; i < 6; ++i) {
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, width, height, 0, glFormat, GL_UNSIGNED_BYTE, data[i]);
  }

  // Generate mipmaps and bind the texture
  glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
  glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

  // Construct our actual texture object
  texture = OVR::GlTexture(texId, GL_TEXTURE_CUBE_MAP);

  // Free our image data
  for (int i = 0; i < 6; ++i) {
    free(data[i]);
  }

  // Wait for the upload to complete.
  glFinish();
  return true;
}
예제 #7
0
OVR::String FullFilePath(OVR::String & fileStr) {
  OVR::String base = CURRENT_BASE_DIR;
  base.StripTrailing("/");
  // TODO: Strip leading "/" in fileStr
  return base + "/" + fileStr;
}