Вторник, 25 Июня 2019, 14:31

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Форум игроделов » Программирование » C/C++ » как за раз удалить массив текстур SDL2 ?
как за раз удалить массив текстур SDL2 ?
AlkoshaДата: Суббота, 23 Августа 2014, 03:02 | Сообщение # 1
участник
Сейчас нет на сайте
Текстуры объявлены следующим образом.
SDL_Texture* texSpr[256];
Чтоб их удалить, нужно проходиться по массиву, тем более нужно ещё знать размер массива. Так как не всегда кол-во texSpr достигает значения 256.
Думал вектором объявить , да вот столкнулся с проблемой при добавлении новых элементов массива (которые добавляются не всегда по порядку). А именно, не знаю как корректно прописать push_back в данной ситуации.


Сообщение отредактировал Alkosha - Суббота, 23 Августа 2014, 03:03
MrFiringДата: Суббота, 23 Августа 2014, 08:14 | Сообщение # 2
был не раз
Сейчас нет на сайте
Если чуть-чуть подумать можно сделать вывод,что незагруженная текстура не будет ничего делать с элементом массива так или запишет туда NULL?
Можно сделать вот так:
Код

int Counter = 0;

for(int i = 0; i < 256;i++)
{
    if(textSpr[i] == NULL)
         Counter++;
}

Таким образом можно получить кол-во загруженных элементов массива..Если я правильно понял то тебе это и было нужно
-l33t-h4xx-Дата: Суббота, 23 Августа 2014, 08:30 | Сообщение # 3
участник
Сейчас нет на сайте
Цитата Alkosha ()
тем более нужно ещё знать размер массива.

Обычно в таком случае люди хранят размер массива в отдельной переменной, но, зная любовь славянского мужика к непредсказуемости, не буду этого советовать.
Статический массив для динамический данных - ужасная идея, используй malloc или векторы/списки.

Цитата Alkosha ()
не знаю как корректно прописать push_back в данной ситуации.

Покажи нам, как ты пишешь. Так?
Код
std::vector <SDL_Texture*> texSpr;
texSpr.push_back(SDL_CreateTextureFromSurface(/*аргументы по вкусу*/));




Как правильно задавать вопросы

Сообщение отредактировал -l33t-h4xx- - Суббота, 23 Августа 2014, 08:33
MrFiringДата: Суббота, 23 Августа 2014, 08:37 | Сообщение # 4
был не раз
Сейчас нет на сайте
Цитата -l33t-h4xx- ()
Хочу также на всякий случай добавить, что "за раз" ничего никогда не удаляется. Так не бывает.

Так-то да лучше попариться денёк...Но потом проблем не будет


Сообщение отредактировал MrFiring - Суббота, 23 Августа 2014, 08:40
AlkoshaДата: Суббота, 23 Августа 2014, 23:10 | Сообщение # 5
участник
Сейчас нет на сайте
Цитата -l33t-h4xx- ()
Покажи нам, как ты пишешь. Так?


ну пока у меня обычным массивом, а не вектором.
Код
SDL_Texture* texSpr[256];
texSpr[nomer_kadra] = IMG_LoadTexture(renderer, filename);

Ни каких сюрфейсов.

Цитата -l33t-h4xx- ()
Хочу также на всякий случай добавить, что "за раз" ничего никогда не удаляется. Так не бывает.


Ну тогда думаю проще будет всё же стандартным массивом и оставить, и очистку выполнять в цикле.
Разница в отличии от вектора разве что будет только в этом.
Цитата -l33t-h4xx- ()
Обычно в таком случае люди хранят размер массива в отдельной переменной

Ну и в выделении области памяти, конечно же.

Но правильным ли будет такое решение...не знаю даже.

Добавлено (23.08.2014, 23:10)
---------------------------------------------
И ещё вопросец по динамическому массиву.
Вот объявлен он у меня так char **bitmap=new char *[64];
Пробую его удалить так delete[] collisMap.bitmap; - ничего не происходит. Как массив и его содержимое были так и остались на месте.

Сообщение отредактировал Alkosha - Суббота, 23 Августа 2014, 16:52
goldsphereДата: Суббота, 23 Августа 2014, 23:29 | Сообщение # 6
заслуженный участник
Сейчас нет на сайте
Alkosha, в цикле надо удалять
for int i ...
delete [] collisMap.bitmap[i];

ТК у тебя двухмерный массив.
http://cppstudio.com/post/432/


FinderX - Android Аркада
AlkoshaДата: Воскресенье, 24 Августа 2014, 03:22 | Сообщение # 7
участник
Сейчас нет на сайте
Цитата goldsphere ()
ТК у тебя двухмерный массив.
http://cppstudio.com/post/432/


Странно.
// удаление двумерного динамического массива
for (int count = 0; count < 2; count++)
delete []ptrarray[count];

Но когда я у себя сделал
for(int i=0;i<63;i++)
delete[] collisMap.bitmap[i];
То получил удаление только первой строки...

Даже не первой строки, а лишь её части


Сообщение отредактировал Alkosha - Воскресенье, 24 Августа 2014, 03:29
LertmindДата: Воскресенье, 24 Августа 2014, 05:58 | Сообщение # 8
заслуженный участник
Сейчас нет на сайте
Alkosha, там по ссылке код немного неправильный, надо после ещё удалить память для указателей float*.
Код
float **ptrarray = new float* [2];
for (int count = 0; count < 2; count++)
      ptrarray[count] = new float [5];

for (int count = 0; count < 2; count++)
      delete [] ptrarray[count];
delete [] ptrarray;
*ptrarray = 0;

И ты хотел написать:
for(int i=0;i<64;i++)
delete[] collisMap.bitmap[i];


Сообщение отредактировал Lertmind - Воскресенье, 24 Августа 2014, 05:59
OpenGOOДата: Воскресенье, 24 Августа 2014, 12:34 | Сообщение # 9
почти ветеран
Сейчас нет на сайте
Цитата Alkosha ()
for(int i=0;i<63;i++) delete[] collisMap.bitmap[i];

Код
for(int i=0;i<size;++i) {
         delete collisMap.bitmap[i];
}

delete[] collisMap.bitmap;


Еще как вариант можно использовать умные указатели, тогда можно будет удалить массив за раз

Еще один вариант набросал (не проверял)

Код
class Texture
{
      SDL_Texture* m_tex;

      public:
          Texture()
          {
              m_tex = nullptr;
          }

          ~Texture()
          {
              if (m_tex) {
                  SDL_DestroyTexture(m_tex);
                  m_tex = nullptr;
              }
          }
            
          bool load(const std::string &filename, SDL_Renderer *renderer)
          {
              m_tex = IMG_LoadTexture(renderer, filename);
              return (m_tex != nullptr);
          }
            
          bool isNull() const { return (m_tex == nullptr); }

          operator SDL_Texture*() { return m_tex; }
            
      private:
          Texture(const Texture &);
          Texture& operator=(const Texture &);
};


Пример использования

Код
Texture texSpr[256];       
texSpr[nomer_kadra].load(filename, renderer);

SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texSpr[nomer_kadra], NULL, NULL);
SDL_RenderPresent(renderer);

SDL_Delay(2000);


Мои проекты:
- Свободный и открытый клон World Of Goo
- TrueEngine2D (2D игровой фреймворк основанный на FreeBASIC)

[GameMaker: Studio v1.4.1772]


Сообщение отредактировал OpenGOO - Воскресенье, 24 Августа 2014, 14:49
AlkoshaДата: Воскресенье, 24 Августа 2014, 14:26 | Сообщение # 10
участник
Сейчас нет на сайте
Цитата OpenGOO ()
Texture texSpr[256];    
texSpr[nomer_kadra].load(filename, renderer);


У меня несколько иначе.
У меня в одном объекте класса заключён массив текстур, а не на каждый объект класса по текстуре.

И я вот что думаю. Если уничтожить объект, то и указатели на текстуры должны уничтожиться. Следовательно, и память должна освободиться ?
OpenGOOДата: Воскресенье, 24 Августа 2014, 14:38 | Сообщение # 11
почти ветеран
Сейчас нет на сайте
Цитата Alkosha ()
И я вот что думаю. Если уничтожить объект, то и указатели на текстуры должны уничтожиться. Следовательно, и память должна освободиться ?

Это зависит от того что что ты в деструкторе объекта написал.


Мои проекты:
- Свободный и открытый клон World Of Goo
- TrueEngine2D (2D игровой фреймворк основанный на FreeBASIC)

[GameMaker: Studio v1.4.1772]
-l33t-h4xx-Дата: Понедельник, 25 Августа 2014, 19:00 | Сообщение # 12
участник
Сейчас нет на сайте
Цитата Alkosha ()
Следовательно, и память должна освободиться ?

Смерть указателя не означает смерти памяти, на которую он указывал.
Цитата Alkosha ()
Как массив и его содержимое были так и остались на месте.

"Удаление" памяти не означает её исчезновения: блок памяти просто помечается как свободный. Конечно, содержание массива поэтому и не исчезает.
Цитата goldsphere ()
ТК у тебя двухмерный массив.

Массив указателей не обязательно означает двухмерный массив.

Вот. А о чём остальная тема, я уже не понимаю. Си надо учить, кароч.


Как правильно задавать вопросы
AlkoshaДата: Четверг, 28 Августа 2014, 09:55 | Сообщение # 13
участник
Сейчас нет на сайте
C динамическим массивом и конструктором\деструктором разобрался.

Но вот как создать "в куче" массив определённого объекта ?

пробовал myObject *obj [255]= new myObject; (и так пробовал myObject *obj = new myObject[255];)
Компилятор ругается (точное содержание его ругани не запомнил).
Конструктор и деструктор в классе присутствует. Один объект создаётся\уничтожается корректно.

Заодно хотелось бы узнать, как этот массив потом дэстройнуть.
Snake174Дата: Четверг, 28 Августа 2014, 10:07 | Сообщение # 14
участник
Сейчас нет на сайте
Цитата
Но вот как создать "в куче" массив определённого объекта ?

Код

myObject *obj[ 255 ];

obj[0] = new myObject(...);
...
obj[ 254 ] = new myObject(...);

if (obj[0])
{
   delete obj[0];
   obj[0] = 0;
}
...
if (obj[ 254 ])
{
   delete obj[ 254 ];
   obj[ 254 ] = 0;
}


Не следует обманывать инспектора
Pipmak Assistant
Love2D Exporter
Love2D-Helpers
Old Consoles Games


Сообщение отредактировал Snake174 - Четверг, 28 Августа 2014, 10:13
ArchidoДата: Четверг, 28 Августа 2014, 15:51 | Сообщение # 15
Сэнсэй
Сейчас нет на сайте
Alkosha
Надо срочно читать Страуструпа


C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
SaiteiДата: Четверг, 28 Августа 2014, 16:31 | Сообщение # 16
старожил
Сейчас нет на сайте
Цитата Snake174 ()
myObject *obj[ 255 ];

offtop: это же массив указателей, да?
AlkoshaДата: Четверг, 28 Августа 2014, 19:06 | Сообщение # 17
участник
Сейчас нет на сайте
Цитата Snake174 ()
myObject *obj[ 255 ];

obj[0] = new myObject(...);


вот тут на второй строке пишет
Цитата
E:\TURBO\platform3\main.cpp|808|error: 'tileTex' does not name a type|


(tileTex - это то же, что и в вашем примере obj)
Snake174Дата: Пятница, 29 Августа 2014, 12:12 | Сообщение # 18
участник
Сейчас нет на сайте
Цитата
offtop: это же массив указателей, да?

Ну да )

Цитата
вот тут на второй строке пишет ...

Больше кода!!!


Не следует обманывать инспектора
Pipmak Assistant
Love2D Exporter
Love2D-Helpers
Old Consoles Games
AlkoshaДата: Воскресенье, 31 Августа 2014, 10:24 | Сообщение # 19
участник
Сейчас нет на сайте
Код

class myTileTex
{
     public:
     bool mirror=false;
     SDL_Rect rect;
     SDL_Texture * tex;
     myTileTex()
     {
         tex=nullptr;
     };
     void load( char* filename )
     {
     tex = IMG_LoadTexture(renderer, filename);
     SDL_QueryTexture(tex, NULL, NULL, &rect.w, &rect.h);
     }
     ~myTileTex()
     {
           if (tex) {
                 SDL_DestroyTexture(tex);
                 tex= nullptr;
               }
     }
};

myTileTex *tileTex[ 255 ];
tileTex[0] = new myTileTex();

Добавлено (31.08.2014, 10:24)
---------------------------------------------
Всё-таки вот такое объявление сработало.

Код

myTileTex *tileTex = new myTileTex[255];


Прога пашет норм, а вот по завершению, если выйти из неё - крашит.

ТайлТєкс взаимосвязан с классом лэйер.
При загрузке
Код
layer1->SetTilePos(a,b,c);

на лэйер (слой) добавляются тайлтэксы (картинки разного размера, так что тайлами их сложно назвать)
Код

class layer
{
int r=255,g=255,b=255;
public:
float far;
int tilenum;
SDL_Rect position[255];
int indextile[255];
layer()
{
tilenum=0;
}

void RGB(int R,int G,int <img src="http://s12.ucoz.net/sm/1/cool.gif" border="0" align="absmiddle" alt="cool" />
{
     r=R;g=G;b=B;
}
void mirror()
{
   tileTex[tilenum].mirror=true;
}

   void SetTilePos(int i,int x,int y)
     {

   position[tilenum].x = x*32; // установка позиции тайлов
   position[tilenum].y = y*32;

   indextile[tilenum]= i;
   tilenum++;
     }

void display(){

for(int i=0;i<tilenum; i++)
{

SDL_Rect DestRb1;
DestRb1.x = position[i].x-cum.x/far;
DestRb1.y = position[i].y-cum.y;

DestRb1.w =(tileTex[indextile[i]].rect.w);
DestRb1.h =(tileTex[indextile[i]].rect.h);
if(DestRb1.x>0-DestRb1.w&&DestRb1.x<800){

int r1,g1,b1;

if(r>=256||g>=256||b>=256)
     {
          if(r>=256)int r1=r-255;
           else r1=0;
      if(g>=256)int g1=g-255;
       else g1=0;
      if(b>=256)int b1=b-255;
       else b1=0;

SDL_SetTextureColorMod(tileTex[indextile[i]].tex,r1,g1,b1);
     }
     else
     SDL_SetTextureColorMod(tileTex[indextile[i]].tex,0,0,0);

SDL_SetTextureBlendMode(tileTex[indextile[i]].tex,SDL_BLENDMODE_BLEND );

if(tileTex[i].mirror)
{
SDL_RendererFlip flip = SDL_FLIP_HORIZONTAL;
SDL_RenderCopyEx(renderer, tileTex[indextile[i]].tex ,  NULL, &DestRb1, NULL, NULL, flip);
}else
SDL_RenderCopy(renderer, tileTex[indextile[i]].tex ,  NULL, &DestRb1);//маска

if(r>=256||g>=256||b>=256)
     {
  if(r>=256) r1=255;
  else r1=r;
if(g>=256) g1=255;
else g1=g;
if(b>=256) b1=255;
else b1=b;
         SDL_SetTextureColorMod(tileTex[indextile[i]].tex,r1,g1,b1);
    }
else SDL_SetTextureColorMod(tileTex[indextile[i]].tex,r,g,b);

SDL_SetTextureBlendMode(tileTex[indextile[i]].tex,SDL_BLENDMODE_ADD );

if(tileTex[i].mirror)
{
SDL_RendererFlip flip = SDL_FLIP_HORIZONTAL;
SDL_RenderCopyEx(renderer, tileTex[indextile[i]].tex ,  NULL, &DestRb1, NULL, NULL, flip);
}else
SDL_RenderCopy(renderer, tileTex[indextile[i]].tex,  NULL, &DestRb1);

}
}
}
~layer()
     {

         delete[] tileTex;

     }
};

layer *layer1= new layer;
layer *layer2= new layer;


Код

class myTileTex
{
     public:
     bool mirror=false;
     SDL_Rect rect;
     SDL_Texture * tex;
     myTileTex()
     {
         tex=nullptr;
     };
     void load( char* filename )
     {
     tex = IMG_LoadTexture(renderer, filename);
     SDL_QueryTexture(tex, NULL, NULL, &rect.w, &rect.h);
     }
     ~myTileTex()
     {
           if (tex) {
                 SDL_DestroyTexture(tex);
                 tex= nullptr;
               }
     }
};

myTileTex *tileTex = new myTileTex[255];


по завершению выполняю.
Код
delete [] layer1;
delete [] layer2;


Прога стала крашить после того, как я сделал тайлтэкс и лэйер "в куче". До этого нормально завершало программу.
-l33t-h4xx-Дата: Воскресенье, 31 Августа 2014, 12:48 | Сообщение # 20
участник
Сейчас нет на сайте
Alkosha, что-то не видно tileTex среди членов класса layer, тем не менее layer считает себя вправе уничтожать tileTex в своём деструкторе. Может, объяснить ему его права получше? А то layer1 удаляй tileTex, layer2 удаляй - в результате одна и та же память освобождается два раза. Я бы тоже покрашился от такого.


Как правильно задавать вопросы

Сообщение отредактировал -l33t-h4xx- - Воскресенье, 31 Августа 2014, 13:05
Форум игроделов » Программирование » C/C++ » как за раз удалить массив текстур SDL2 ?
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Все права сохранены. GcUp.ru © 2008-2019 Рейтинг