我对SDL_Texture的理解是:
我正确吗?
我正在制作一个应用程序,可以在渲染图像之前一次从图像文件一次创建很多纹理,因为图像非常大,并且SDL_CreateTextureFromSurface()需要很长时间。当我依次使用SDL_RenderCopy()和SDL_RenderPresent()渲染它们时,VRAM的使用量逐渐增加,并且在达到最大使用量后应用程序变慢。
我想从VRAM中释放纹理,但又不想从主内存中释放纹理,因为重新创建纹理需要很长时间。有可能吗?
这是最小代码。它可以工作到专用GPU内存使用率达到100%为止。在那之后,它变得非常缓慢。 (Windows10,Visual Studio 2017,NVIDIA P6000)
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <filesystem>
#include <thread>
#include <chrono>
#include "SDL.h"
#include "SDL_image.h"
int main(int argc, char** argv) {
std::vector<SDL_Texture*> texture_list;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow( "", 0, 0, 7680, 4320, SDL_WINDOW_BORDERLESS);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
namespace fs = std::experimental::filesystem;
for ( auto ent : fs::recursive_directory_iterator("c:\\picture\\1k") ) {
if(!fs::is_directory(ent)){
auto f = ent.path().generic_string();
auto surface = IMG_Load(f.c_str());
std::cout << "file:" << f << std::endl;
auto tex = SDL_CreateTextureFromSurface(renderer, surface);
if(!tex){
std::cout << "SDL_CreateTextureFromSurface error" << std::endl;
std::cout << SDL_GetError() << std::endl;
}
texture_list.push_back(tex);
SDL_FreeSurface(surface);
}
}
while (true) {
for (auto tex : texture_list) {
if(SDL_RenderClear(renderer) != 0){
std::cout << "SDL_RenderClear error" << std::endl;
std::cout << SDL_GetError() << std::endl;
}
if(SDL_RenderCopy(renderer, tex, NULL, NULL) < 0){
std::cout << "SDL_RenderCopy error" << std::endl;
std::cout << SDL_GetError() << std::endl;
}
SDL_RenderPresent(renderer);
SDL_Delay(1);
//std::cout << cnt++ << std::endl;
SDL_Event event;
if(SDL_PollEvent(&event)){
std::cout << event.type << std::endl;
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_q:
exit(0);
}
break;
}
}
}
}
return 0;
}
答案 0 :(得分:0)
每个纹理一次都可以发生!
(也许您打算这样做,但似乎没有用;幻灯片的设计更短,更好)
在主循环开始时,每次主循环迭代应该只调用一次SDL_RenderClear
。同样,您应该只在主循环的末尾与SDL_RenderPresent
一起呼叫SDL_PollEvent
while (true) {
if(SDL_RenderClear(renderer) != 0){
std::cout << "SDL_RenderClear error" << std::endl;
std::cout << SDL_GetError() << std::endl;
}
for (auto tex : texture_list) {
if(SDL_RenderCopy(renderer, tex, NULL, NULL) < 0){
std::cout << "SDL_RenderCopy error" << std::endl;
std::cout << SDL_GetError() << std::endl;
}
}
SDL_RenderPresent(renderer);
SDL_Delay(1);
//std::cout << cnt++ << std::endl;
SDL_Event event;
if(SDL_PollEvent(&event)){
std::cout << event.type << std::endl;
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_q:
exit(0);
}
break;
}
}
}
请注意,SDL_RenderCopy
缺少目标矩形,因此每个纹理都将在前一个纹理上绘制...
如果您要做想要幻灯片放映。您最好先 not 先创建所有纹理,然后尝试在幻灯片切换时按需构建它们,或者创建单流纹理并更新像素(可能如果您使用不同尺寸的图像,效果不佳