非同期で読み込んだ画像が描画されない原因が知りたい

提示コードのvoid Engine::SpriteRenderer::Render()関数部ですが const SDL_Texture* texture = IMG_LoadTexture(Context::GetRenderer(),"./tile4.png");を使うと正常に描画できるのですがsprite->texture を使って描画すると描画されません。これはなぜでしょうか? 非同期で画像ロードしてしっかりと待機していて同じポインターを指しているのですが原因がわかりません。デストラクタ等は定義、宣言していません。

画像が描画できない原因が知りたい

提示のコンソールログのように取得時と利用時でアドレスを表示させましたが同じ場所を指しています。
また、提示コードのように、その場でロードした場合は正常に描画され、原因がtexture変数にあることがわかりました。
SDL_GetError()を実行しましたが何も表示されていません。

0x7fe4a4000dd0 0x7fe4a4000dd0 0x7fe4a4000dd0

#ソースコード

画像ロード関数

cpp

1#include "Resource.hpp"2#include "Context.hpp"3#include <SDL2/SDL.h>4#include <SDL2/SDL_image.h>5#include <vector>6#include <future>7#include <iostream>8#include <glm/glm.hpp>9#include <thread>10#include <mutex>11#include <condition_variable>12 13std::vector<Engine::Sprite*> Engine::Resource::sprites;14std::vector<std::string> Engine::Resource::nowLoad;15std::mutex Engine::Resource::loadMutex;16std::condition_variable Engine::Resource::loadCV;17 18Engine::Sprite* Engine::Resource::LoadSprite(const char* filePath)19{20 std::unique_lock<std::mutex> lock(loadMutex);21 22 // 他のスレッドが同じ画像をロード中であれば待機23 loadCV.wait(lock, [&filePath]() 24 {25 for(const std::string& path : nowLoad) 26 {27 if (path == std::string(filePath)) 28 {29 return false;30 }31 }32 33 return true;34 });35 36 //スプライトリストから取り出す37 for (Sprite *s : sprites)38 {39 if (s->path == std::string(filePath))40 {41 // std::cout << "found sprite" << std::endl;42 return s;43 }44 }45 46 //std::cout << "new sprite" << std::endl;47 48 // ロード中の画像リストに追加49 nowLoad.push_back(std::string(filePath));50 lock.unlock(); // ロックを解除して他のスレッドがロードを開始できるようにする51 52 SDL_Texture* texture = NULL;53 texture = IMG_LoadTexture(Context::GetRenderer(),filePath);54 55 lock.lock(); // ロックを再取得して安全に状態を更新する56 if(texture == NULL)57 {58 std::cout<<SDL_GetError()<<std::endl;59 }60 61 int i = 0;62 for(const std::string& s : nowLoad)63 {64 if(s == filePath)65 {66 break; 67 }68 69 i++;70 }71 72 nowLoad.erase(nowLoad.begin() + i);73 74 75 76 int width,height;77 SDL_QueryTexture(texture,NULL,NULL,&width,&height);78 79 80 81 sprites.push_back(new Sprite(std::string(filePath),texture,glm::ivec2(width,height)));82 83 // 画像のロードが完了したことを通知84 loadCV.notify_all();85 86 return sprites.back();87 88 89}

利用

cpp

1#include "PlayerControl.hpp"2#include <SpriteRenderer.hpp>3#include <Resource.hpp>4 5PlayerControl::PlayerControl(Engine::GameObject* g) : Engine::Component(g)6{7 8}9 10std::vector<std::future<void>> PlayerControl::PreLoad()11{12 futures.push_back(std::async(std::launch::async,[this]()13 {14 Engine::SpriteRenderer *sp = (Engine::SpriteRenderer*)gameObject->GetComponent<Engine::SpriteRenderer>();15 sp->sprite = Engine::Resource::LoadSprite("./tile4.png");16 17 std::cout<<sp->sprite->texture<<std::endl;18 }));19 20 21 return std::move(futures);22}23 24void PlayerControl::Start()25{26 27}28 29void PlayerControl::Update()30{31 32}

待機側 

cpp

12void Engine::Scene::PreLoad()3{4 std::vector<std::future<void>> futures;5 for(GameObject *g : gameObjects)6 {7 for(std::future<void> &f : g->getPreLoad())8 {9 futures.push_back(std::move(f));10 }11 }12 13 for(std::future<void> &f : futures)14 {15 f.wait();16 }17}18 19 20void Engine::Scene::Loop()21{22 PreLoad();23 24 Awake();25 Start();26 27 while(true)28 {29 Context::ClearBuffer();30 31 if(Context::GetKey(SDL_SCANCODE_ESCAPE) == true)32 {33 break;34 }35 36 Update();37 38 39 Render();40 41 42 Context::RenderBuffer();43 }44}

実行描画

cpp

12void Engine::SpriteRenderer::Render()3{4 5 const SDL_Texture* texture = IMG_LoadTexture(Context::GetRenderer(),"./tile4.png");6 7 std::cout<<" "<<sprite->texture<<std::endl;8 9 10 11 int err = SDL_RenderCopy(Context::GetRenderer(),(SDL_Texture*)texture,&rect,&dest); 12 //int err = SDL_RenderCopy(Context::GetRenderer(),(SDL_Texture*)sprite->texture,&rect,&dest); 13 14 15 std::cout<<SDL_GetError()<<err<<std::endl;16 17 // int err = SDL_RenderCopyEx(Context::GetRenderer(),(SDL_Texture*)sprite->texture,NULL,&rect, 0.0,NULL,SDL_FLIP_VERTICAL); 18}

コメントを投稿

0 コメント