unsigned File::GetChecksum() { if (offset_ || checksum_) return checksum_; #ifdef __ANDROID__ if ((!handle_ && !assetHandle_) || mode_ == FILE_WRITE) #else if (!handle_ || mode_ == FILE_WRITE) #endif return 0; ATOMIC_PROFILE(CalculateFileChecksum); unsigned oldPos = position_; checksum_ = 0; Seek(0); while (!IsEof()) { unsigned char block[1024]; unsigned readBytes = Read(block, 1024); for (unsigned i = 0; i < readBytes; ++i) checksum_ = SDBMHash(checksum_, block[i]); } Seek(oldPos); return checksum_; }
bool Font::SaveXML(Serializer& dest, int pointSize, bool usedGlyphs, const String& indentation) { FontFace* fontFace = GetFace(pointSize); if (!fontFace) return false; ATOMIC_PROFILE(FontSaveXML); SharedPtr<FontFaceBitmap> packedFontFace(new FontFaceBitmap(this)); if (!packedFontFace->Load(fontFace, usedGlyphs)) return false; return packedFontFace->Save(dest, pointSize, indentation); }
FontFace* Font::GetFace(int pointSize) { // In headless mode, always return null Graphics* graphics = GetSubsystem<Graphics>(); if (!graphics) return 0; // For bitmap font type, always return the same font face provided by the font's bitmap file regardless of the actual requested point size if (fontType_ == FONT_BITMAP) pointSize = 0; else pointSize = Clamp(pointSize, MIN_POINT_SIZE, MAX_POINT_SIZE); HashMap<int, SharedPtr<FontFace> >::Iterator i = faces_.Find(pointSize); if (i != faces_.End()) { if (!i->second_->IsDataLost()) return i->second_; else { // Erase and reload face if texture data lost (OpenGL mode only) faces_.Erase(i); } } ATOMIC_PROFILE(GetFontFace); switch (fontType_) { case FONT_FREETYPE: return GetFaceFreeType(pointSize); case FONT_BITMAP: return GetFaceBitmap(pointSize); default: return 0; } }
void CustomGeometry::Commit() { ATOMIC_PROFILE(CommitCustomGeometry); unsigned totalVertices = 0; boundingBox_.Clear(); for (unsigned i = 0; i < vertices_.Size(); ++i) { totalVertices += vertices_[i].Size(); for (unsigned j = 0; j < vertices_[i].Size(); ++j) boundingBox_.Merge(vertices_[i][j].position_); } // Make sure world-space bounding box will be updated OnMarkedDirty(node_); // Resize (recreate) the vertex buffer only if necessary if (vertexBuffer_->GetVertexCount() != totalVertices || vertexBuffer_->GetElementMask() != elementMask_ || vertexBuffer_->IsDynamic() != dynamic_) vertexBuffer_->SetSize(totalVertices, elementMask_, dynamic_); if (totalVertices) { unsigned char* dest = (unsigned char*)vertexBuffer_->Lock(0, totalVertices, true); if (dest) { unsigned vertexStart = 0; for (unsigned i = 0; i < vertices_.Size(); ++i) { unsigned vertexCount = 0; for (unsigned j = 0; j < vertices_[i].Size(); ++j) { *((Vector3*)dest) = vertices_[i][j].position_; dest += sizeof(Vector3); if (elementMask_ & MASK_NORMAL) { *((Vector3*)dest) = vertices_[i][j].normal_; dest += sizeof(Vector3); } if (elementMask_ & MASK_COLOR) { *((unsigned*)dest) = vertices_[i][j].color_; dest += sizeof(unsigned); } if (elementMask_ & MASK_TEXCOORD1) { *((Vector2*)dest) = vertices_[i][j].texCoord_; dest += sizeof(Vector2); } if (elementMask_ & MASK_TANGENT) { *((Vector4*)dest) = vertices_[i][j].tangent_; dest += sizeof(Vector4); } ++vertexCount; } geometries_[i]->SetVertexBuffer(0, vertexBuffer_); geometries_[i]->SetDrawRange(primitiveTypes_[i], 0, 0, vertexStart, vertexCount); vertexStart += vertexCount; } vertexBuffer_->Unlock(); } else ATOMIC_LOGERROR("Failed to lock custom geometry vertex buffer"); } else { for (unsigned i = 0; i < geometries_.Size(); ++i) { geometries_[i]->SetVertexBuffer(0, vertexBuffer_); geometries_[i]->SetDrawRange(primitiveTypes_[i], 0, 0, 0, 0); } } vertexBuffer_->ClearDataLost(); }
bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, const void* data) { ATOMIC_PROFILE(SetTextureData); if (!object_.name_ || !graphics_) { ATOMIC_LOGERROR("No texture created, can not set data"); return false; } if (!data) { ATOMIC_LOGERROR("Null source for setting data"); return false; } if (level >= levels_) { ATOMIC_LOGERROR("Illegal mip level for setting data"); return false; } if (graphics_->IsDeviceLost()) { ATOMIC_LOGWARNING("Texture data assignment while device is lost"); dataPending_ = true; return true; } if (IsCompressed()) { x &= ~3; y &= ~3; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || width <= 0 || height <= 0) { ATOMIC_LOGERROR("Illegal dimensions for setting data"); return false; } graphics_->SetTextureForUpdate(this); bool wholeLevel = x == 0 && y == 0 && width == levelWidth && height == levelHeight; unsigned format = GetSRGB() ? GetSRGBFormat(format_) : format_; if (!IsCompressed()) { if (wholeLevel) glTexImage2D(target_, level, format, width, height, 0, GetExternalFormat(format_), GetDataType(format_), data); else glTexSubImage2D(target_, level, x, y, width, height, GetExternalFormat(format_), GetDataType(format_), data); } else { if (wholeLevel) glCompressedTexImage2D(target_, level, format, width, height, 0, GetDataSize(width, height), data); else glCompressedTexSubImage2D(target_, level, x, y, width, height, format, GetDataSize(width, height), data); } graphics_->SetTexture(0, 0); return true; }