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; }
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; }