// Create a Synchronizer object for a PDF file. // It creates either a SyncTex or PdfSync object // based on the synchronization file found in the folder containing the PDF file. int Synchronizer::Create(const WCHAR *pdffilename, PdfEngine *engine, Synchronizer **sync) { if (!sync || !engine) return PDFSYNCERR_INVALID_ARGUMENT; const WCHAR *fileExt = path::GetExt(pdffilename); if (!str::EqI(fileExt, L".pdf")) return PDFSYNCERR_INVALID_ARGUMENT; ScopedMem<WCHAR> baseName(str::DupN(pdffilename, fileExt - pdffilename)); // Check if a PDFSYNC file is present ScopedMem<WCHAR> syncFile(str::Join(baseName, PDFSYNC_EXTENSION)); if (file::Exists(syncFile)) { *sync = new Pdfsync(syncFile, engine); return *sync ? PDFSYNCERR_SUCCESS : PDFSYNCERR_OUTOFMEMORY; } // check if SYNCTEX or compressed SYNCTEX file is present ScopedMem<WCHAR> texGzFile(str::Join(baseName, SYNCTEXGZ_EXTENSION)); ScopedMem<WCHAR> texFile(str::Join(baseName, SYNCTEX_EXTENSION)); if (file::Exists(texGzFile) || file::Exists(texFile)) { // due to a bug with synctex_parser.c, this must always be // the path to the .synctex file (even if a .synctex.gz file is used instead) *sync = new SyncTex(texFile, engine); return *sync ? PDFSYNCERR_SUCCESS : PDFSYNCERR_OUTOFMEMORY; } return PDFSYNCERR_SYNCFILE_NOTFOUND; }
bool ModelPackager::copyTextures(const QString& oldDir, const QDir& newDir) { QString errors; for (auto texture : _textures) { QString oldPath = oldDir + "/" + texture; QString newPath = newDir.path() + "/" + texture; // Make sure path exists if (texture.contains("/")) { QString dirPath = newDir.relativeFilePath(QFileInfo(newPath).path()); newDir.mkpath(dirPath); } QFile texFile(oldPath); if (texFile.exists() && texFile.open(QIODevice::ReadOnly)) { // Check if texture needs to be recoded QFileInfo fileInfo(oldPath); QString extension = fileInfo.suffix().toLower(); bool isJpeg = (extension == "jpg"); bool mustRecode = !(isJpeg || extension == "png"); QImage image = QImage::fromData(texFile.readAll()); // Recode texture if too big if (image.width() > MAX_TEXTURE_SIZE || image.height() > MAX_TEXTURE_SIZE) { image = image.scaled(MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, Qt::KeepAspectRatio); mustRecode = true; } // Copy texture if (mustRecode) { QFile newTexFile(newPath); newTexFile.open(QIODevice::WriteOnly); image.save(&newTexFile, isJpeg ? "JPG" : "PNG"); } else { texFile.copy(newPath); } } else { errors += QString("\n%1").arg(oldPath); } } if (!errors.isEmpty()) { OffscreenUi::asyncWarning(nullptr, "ModelPackager::copyTextures()", "Missing textures:" + errors); qCDebug(interfaceapp) << "ModelPackager::copyTextures():" << errors; return false; } return true; }
osg::Node* traverseAIScene( const std::string& filename, const struct aiScene* aiScene, const struct aiNode* aiNode, TextureMap& textures, const osgDB::Options* options ) const { osg::Geode* geode = new osg::Geode; for ( unsigned int n=0; n<aiNode->mNumMeshes; ++n ) { // Create geometry basic properties const struct aiMesh* mesh = aiScene->mMeshes[ aiNode->mMeshes[n] ]; osg::Geometry* geom = new osg::Geometry; geode->addDrawable( geom ); osg::Vec3Array* va = new osg::Vec3Array(mesh->mNumVertices); osg::Vec3Array* na = (mesh->mNormals ? new osg::Vec3Array(mesh->mNumVertices) : NULL); osg::Vec4Array* ca = (mesh->mColors[0] ? new osg::Vec4Array(mesh->mNumVertices) : NULL); for ( unsigned int i=0; i<mesh->mNumVertices; ++i ) { const aiVector3D& v = mesh->mVertices[i]; (*va)[i].set( v.x, v.y, v.z ); if ( na ) { const aiVector3D& n = mesh->mNormals[i]; (*na)[i].set( n.x, n.y, n.z ); } if ( ca ) { const aiColor4D& c = mesh->mColors[0][i]; (*ca)[i].set( c.r, c.g, c.b, c.a ); } } geom->setVertexArray( va ); if ( na ) { geom->setNormalArray( na ); geom->setNormalBinding( osg::Geometry::BIND_PER_VERTEX ); } if ( ca ) { geom->setColorArray( ca ); geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); } // Create geometry texture coordinates unsigned int unit = 0; const aiVector3D* aiTexCoords = mesh->mTextureCoords[unit]; while ( aiTexCoords!=NULL ) { switch ( mesh->mNumUVComponents[unit] ) { case 1: { osg::FloatArray* ta = new osg::FloatArray(mesh->mNumVertices); for ( unsigned int i=0; i<mesh->mNumVertices; ++i ) (*ta)[i] = aiTexCoords[i].x; geom->setTexCoordArray( unit, ta ); } break; case 2: { osg::Vec2Array* ta = new osg::Vec2Array(mesh->mNumVertices); for ( unsigned int i=0; i<mesh->mNumVertices; ++i ) { const aiVector3D& t = aiTexCoords[i]; (*ta)[i].set( t.x, t.y ); } geom->setTexCoordArray( unit, ta ); } break; case 3: { osg::Vec3Array* ta = new osg::Vec3Array(mesh->mNumVertices); for ( unsigned int i=0; i<mesh->mNumVertices; ++i ) { const aiVector3D& t = aiTexCoords[i]; (*ta)[i].set( t.x, t.y, t.z ); } geom->setTexCoordArray( unit, ta ); } break; } aiTexCoords = mesh->mTextureCoords[++unit]; } // Create geometry primitives osg::ref_ptr<osg::DrawElementsUInt> de[5]; de[1] = new osg::DrawElementsUInt(GL_POINTS); de[2] = new osg::DrawElementsUInt(GL_LINES); de[3] = new osg::DrawElementsUInt(GL_TRIANGLES); de[4] = new osg::DrawElementsUInt(GL_QUADS); de[0] = new osg::DrawElementsUInt(GL_POLYGON); osg::DrawElementsUInt* current = NULL; for ( unsigned int f=0; f<mesh->mNumFaces; ++f ) { const struct aiFace& face = mesh->mFaces[f]; if ( face.mNumIndices>4 ) current = de[0].get(); else current = de[face.mNumIndices].get(); for ( unsigned i=0; i<face.mNumIndices; ++i ) current->push_back( face.mIndices[i] ); } for ( unsigned int i=0; i<5; ++i ) { if ( de[i]->size()>0 ) geom->addPrimitiveSet( de[i].get() ); } // Create textures osg::StateSet* ss = geom->getOrCreateStateSet(); const aiMaterial* aiMtl = aiScene->mMaterials[mesh->mMaterialIndex]; aiReturn texFound = AI_SUCCESS; aiTextureOp envOp = aiTextureOp_Multiply; aiTextureMapMode wrapMode[3] = {aiTextureMapMode_Clamp}; unsigned int texIndex = 0; aiString path; while ( texFound==AI_SUCCESS ) { texFound = aiMtl->GetTexture( aiTextureType_DIFFUSE, texIndex++, &path, NULL, &unit, NULL, &envOp, &(wrapMode[0]) ); if ( unit>0 ) unit--; // The output UV seems to start at 1? if ( texFound!=AI_SUCCESS ) break; std::string texFile(path.data); if ( !osgDB::isAbsolutePath(texFile) ) texFile = getFullPath( filename, texFile ); TextureMap::iterator itr = textures.find(texFile); if ( itr==textures.end() ) { osg::ref_ptr<osg::Texture2D> tex2D = new osg::Texture2D; tex2D->setWrap( osg::Texture::WRAP_S, getWrapMode(wrapMode[0]) ); tex2D->setWrap( osg::Texture::WRAP_T, getWrapMode(wrapMode[1]) ); tex2D->setWrap( osg::Texture::WRAP_R, getWrapMode(wrapMode[2]) ); tex2D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR ); tex2D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR ); tex2D->setImage( osgDB::readImageFile(texFile, options) ); textures[texFile] = tex2D; } ss->setTextureAttributeAndModes( unit, textures[texFile].get() ); if ( unit>0 ) ss->setTextureAttributeAndModes( unit, new osg::TexEnv(getEnvMode(envOp)) ); } // Create materials createMaterialData( ss, aiMtl ); } aiMatrix4x4 m = aiNode->mTransformation; m.Transpose(); // Create the node and continue looking for children osg::ref_ptr<osg::MatrixTransform> mt; mt = new osg::MatrixTransform; mt->setMatrix( osg::Matrixf((float*)&m) ); for ( unsigned int n=0; n<aiNode->mNumChildren; ++n ) { osg::Node* child = traverseAIScene( filename, aiScene, aiNode->mChildren[n], textures, options ); if ( child ) mt->addChild( child ); } mt->addChild( geode ); return mt.release(); }
bool MD2Loader::load( const std::string& fileName ) { size_t pos = fileName.find_last_of("/"); _fileBase = fileName.substr(0, pos+1); _fileName = fileName.substr(pos + 1, fileName.size() - 1); _md2File = new MD2File; std::ifstream f(fileName.c_str(), std::ios_base::binary); // if (!f.good()) { return false; } // f.seekg(std::ios_base::beg); f.read((char*)&_md2File->_header, sizeof(_md2File->_header)); // if (_md2File->_header.ident != 844121161 || _md2File->_header.version != 8) { return false; } if (_md2File->_header.num_skins > 0) { /* Memory allocations */ _md2File->_data.skins = new skin[_md2File->_header.num_skins]; /* Read model data */ f.seekg(_md2File->_header.offset_skins, std::ios_base::beg); f.read((char*)_md2File->_data.skins, sizeof(skin) * _md2File->_header.num_skins); } if (_md2File->_header.num_st > 0) { _md2File->_data.texcoords = new texCoord[_md2File->_header.num_st]; f.seekg(_md2File->_header.offset_st, std::ios_base::beg); f.read((char*)_md2File->_data.texcoords, sizeof(texCoord) * _md2File->_header.num_st); } if (_md2File->_header.num_tris > 0) { _md2File->_data.triangles = new triangle[_md2File->_header.num_tris]; f.seekg(_md2File->_header.offset_tris, std::ios_base::beg); f.read((char*)_md2File->_data.triangles, sizeof(triangle) * _md2File->_header.num_tris); } if (_md2File->_header.num_frames > 0) { _md2File->_data.frames = new frame[_md2File->_header.num_frames]; f.seekg(_md2File->_header.offset_frames, std::ios_base::beg); // for (int i = 0; i < _md2File->_header.num_frames; ++i) { _md2File->_data.frames[i].vs = new vertex[_md2File->_header.num_vertices]; // f.read((char*)&_md2File->_data.frames[i].scale, sizeof(vec3)); f.read((char*)&_md2File->_data.frames[i].translate, sizeof(vec3)); f.read(_md2File->_data.frames[i].name, 16); f.read((char*)_md2File->_data.frames[i].vs, sizeof(vertex) * _md2File->_header.num_vertices); } } // if (_md2File->_header.num_glcmds > 0) { _md2File->_data.glcmds = new int[_md2File->_header.num_glcmds]; f.seekg(_md2File->_header.offset_glcmds, std::ios_base::beg); f.read((char*)_md2File->_data.glcmds, sizeof(int) * _md2File->_header.num_glcmds); } // f.close(); // std::string texFile(fileName.substr(0, fileName.size() - 3)); if (_md2File->_data.skins) { texFile = _fileBase + _md2File->_data.skins->name; _tex = TextureFactory::getInstancePtr()->createTextureFromFile(texFile); if (_tex) { _texName = _md2File->_data.skins->name; return true; } //texFile = _fileBase + _md2File->_data.skins->name; texFile = texFile.substr(0, texFile.size() - 3); } // for (int i = 0; i < _Possible_Extend.size(); ++i) { if (Buddha::FileSystem::getInstancePtr()->isFileExist(texFile + _Possible_Extend[i])) { _tex = TextureFactory::getInstancePtr()->createTextureFromFile(texFile + _Possible_Extend[i]); if (_tex) { size_t pos = texFile.find_last_of('//'); if (pos != std::string::npos) { _texName = texFile.substr(pos + 1, texFile.size() - 1) + _Possible_Extend[i]; } return true; } } } // return false; }
bool TestRenderer::LoadTexture(const std::wstring& filename, ID3D11ShaderResourceView** srv) { FileHandle texFile(CreateFile(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr)); if (!texFile.IsValid()) { LogError(L"Failed to open texture."); return false; } DWORD bytesRead{}; uint32_t fileSize = GetFileSize(texFile.Get(), nullptr); TextureHeader texHeader{}; if (!ReadFile(texFile.Get(), &texHeader, sizeof(texHeader), &bytesRead, nullptr)) { LogError(L"Failed to read texture."); return false; } if (texHeader.Signature != TextureHeader::ExpectedSignature) { LogError(L"Invalid texture file."); return false; } uint32_t pixelDataSize = fileSize - sizeof(TextureHeader); std::unique_ptr<uint8_t[]> pixelData(new uint8_t[pixelDataSize]); if (!ReadFile(texFile.Get(), pixelData.get(), pixelDataSize, &bytesRead, nullptr)) { LogError(L"Failed to read texture data."); return false; } D3D11_TEXTURE2D_DESC td{}; td.ArraySize = texHeader.ArrayCount; td.Format = texHeader.Format; #if USE_SRGB if (td.Format == DXGI_FORMAT_R8G8B8A8_UNORM) { td.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; } else if (td.Format == DXGI_FORMAT_B8G8R8A8_UNORM) { td.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; } #endif td.Width = texHeader.Width; td.Height = texHeader.Height; td.MipLevels = texHeader.MipLevels; td.BindFlags = D3D11_BIND_SHADER_RESOURCE; td.SampleDesc.Count = 1; td.Usage = D3D11_USAGE_DEFAULT; D3D11_SUBRESOURCE_DATA init[20] {}; uint32_t bpp = (uint32_t)BitsPerPixel(td.Format) / 8; ComPtr<ID3D11Texture2D> texture; HRESULT hr = S_OK; // Only try to use mips if width & height are the same size if (td.Width == td.Height && td.MipLevels > 1) { uint32_t width = td.Width; uint32_t height = td.Height; uint8_t* pPixels = pixelData.get(); for (int m = 0; m < (int)td.MipLevels; ++m) { init[m].pSysMem = pPixels; init[m].SysMemPitch = width * bpp; init[m].SysMemSlicePitch = width * height * bpp; width = max(width >> 1, 1); height = max(height >> 1, 1); pPixels += init[m].SysMemSlicePitch; } hr = Device->CreateTexture2D(&td, init, &texture); }