unsigned int __stdcall Texture::Atlas::ThreadLoadTexture( void* data ) { Thread::Work *work = ( Thread::Work* ) data; ThreadDataLoadTexture *loader = ( ThreadDataLoadTexture* ) work->data; //__log.PrintInfo( Filelevel_DEBUG, "Texture::Atlas::ThreadLoadTexture => begin: data[%d] size[%d; %d]", loader->data->getLength(), loader->size.width, loader->size.height ); // ImageLoader image; if( !image.LoadFromBuffer( ( Byte* ) loader->data->getData(), loader->data->getLength() ) ) { __log.PrintInfo( Filelevel_ERROR, "Texture::Atlas::ThreadLoadTexture => image.LoadFromBuffer failed" ); work->status = Thread::THREAD_WORK_STATUS_ERROR; return 1; } Dword *dst = ( Dword* ) loader->atlas->textureData.getData(), *src = ( Dword* ) image.GetImageData(); for( Dword y = 0; y < image.GetImageSize().height; ++y ) { memcpy( dst + ( loader->item->rect.top + y ) * loader->atlas->size.width + loader->item->rect.left, src + y * image.GetImageSize().width, image.GetImageSize().width * 4 ); } loader->atlas->FlushToGPU(); //done delete loader->data; delete loader; work->status = Thread::THREAD_WORK_STATUS_DONE; //__log.PrintInfo( Filelevel_DEBUG, "Texture::Atlas::ThreadLoadTexture => done" ); return 0; }//ThreadLoadTexture
/* ============= LoadTexture ============= */ Texture::Atlas::Item* Texture::Atlas::LoadTexture( const std::string& textureFileName, const bool forceLoad ) { ImageLoader image; Size size( 0, 0 ); memory *deferredLoadingData; if( forceLoad ) { if( !image.LoadFromFile( textureFileName ) ) { __log.PrintInfo( Filelevel_ERROR, "Texture::Atlas::LoadTexture => file not found '%s'", textureFileName.c_str() ); return NULL; } size = image.GetImageSize(); } else { deferredLoadingData = new memory(); __fileManager->GetFile( textureFileName, *deferredLoadingData ); size = ImageLoader::GetImageSizeFromBuffer( ( Byte* ) deferredLoadingData->getData(), deferredLoadingData->getLength() ); } if( !this->atlas.HasPlace( size ) ) { __log.PrintInfo( Filelevel_ERROR, "Texture::Atlas::LoadTexture => atlas can't find needed place [ %d; %d ]", size.width, size.height ); return NULL; } Texture::Atlas::Item *item = new Texture::Atlas::Item(); Rect< Dword > fullRect; this->atlas.Cut( size + Size( this->borderPerItem * 2, this->borderPerItem * 2 ), &fullRect ); item->rect = Rect< Dword >( fullRect.left + 1, fullRect.top + 1, fullRect.right - 1, fullRect.bottom - 1 ); item->textureFileName = textureFileName; Vec2 scale( float( item->rect.right - item->rect.left + 1 ) / float( this->size.width ), float( item->rect.bottom - item->rect.top + 1 ) / float( this->size.height ) ); Vec2 translate( float( item->rect.left ) / float( this->size.width ), float( item->rect.top ) / float( this->size.height ) ); item->matTransform.Identity(); Mat4 matTranslate, matScale, matInvTranslate, matInvScale; matTranslate.Identity(); matInvTranslate.Identity(); matScale.Identity(); matInvScale.Identity(); matScale[ 0 ][ 0 ] = scale.x; matScale[ 1 ][ 1 ] = scale.y; matInvScale[ 0 ][ 0 ] = 1.0f / scale.x; matInvScale[ 1 ][ 1 ] = 1.0f / scale.y; matTranslate[ 0 ][ 3 ] = translate.x; matTranslate[ 1 ][ 3 ] = translate.y; matInvTranslate[ 0 ][ 3 ] = -translate.x; matInvTranslate[ 1 ][ 3 ] = -translate.y; //__log.PrintInfo( Filelevel_DEBUG, "matrix translate: [ %3.3f; %3.3f ]", translate.x, translate.y ); //__log.PrintInfo( Filelevel_DEBUG, "matrix scale: [ %3.3f; %3.3f ]", scale.x, scale.y ); item->matTransform = matTranslate * matScale; item->matInvTransform = matInvScale * matInvTranslate; //размещение картинки в текстуре if( forceLoad ) { //this->Bind(); Dword *dst = ( Dword* ) this->textureData.getData(), *src = ( Dword* ) image.GetImageData(); for( Dword y = 0; y < image.GetImageSize().height; ++y ) { memcpy( dst + ( item->rect.top + y ) * this->size.width + item->rect.left, src + y * image.GetImageSize().width, image.GetImageSize().width * 4 ); } //glTexImage2D( GL_TEXTURE_2D, 0, 4, this->size.width, this->size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->textureData.getData() ); //this->Unbind(); this->FlushToGPU(); } else { // TODO: здесь отложенная загрузка // класть в стек deferredLoadingData, указатель на атлас и Texture::Atlas::Item item ThreadDataLoadTexture *loader = new ThreadDataLoadTexture(); loader->data = deferredLoadingData; loader->size = size; loader->atlas = this; loader->item = item; extern Thread::Pipeline *__workPipeline; __workPipeline->Add( loader, Texture::Atlas::ThreadLoadTexture ); } this->textures.push_back( item ); return item; }//LoadTexture