PMG
https://www.forum.pmg.org.ru/

Работа с массивом текстуры
https://www.forum.pmg.org.ru/viewtopic.php?f=1&t=2933
Страница 1 из 1

Автор:  gkv311 [ 04 июн 2007 23:51 ]
Заголовок сообщения:  Работа с массивом текстуры

Заранее очень сильно извиняюсь :oops: , что задаю такие глупые вопросы.
В примерах используется загрузка текстуры из BMP-файла.
Код:
int LoadGLTextures()
{
   int Status=FALSE;// Status Indicator

   AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture
   memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL
   if (TextureImage[0]=LoadBMP(strTemp))
   {
      Status=TRUE; // Set The Status To TRUE
        syratio=(80.0f*TextureImage[0]->sizeY)/TextureImage[0]->sizeX;     
      glGenTextures(1, &texture[0]); // Create The Texture

      // Typical Texture Generation Using Data From The Bitmap
      glBindTexture(GL_TEXTURE_2D, texture[0]);
      glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
   }

   if (TextureImage[0]) // If Texture Exists
   {
      if (TextureImage[0]->data) // If Texture Image Exists
      {free(TextureImage[0]->data); // Free The Texture Image Memory
      }

      free(TextureImage[0]); // Free The Image Structure
   }

   return Status;// Return The Status
}


Насколько я понимаю, сама картинка засовывается в TextureImage[0]->data.
Собственно вопрос: что из себя представляет этот массив. Как можно ручками его изменить (то есть, как по каждому цвету и по каждому пикселу там всё храниться; как логичнее модифицировать это).

Автор:  WR [ 05 июн 2007 12:35 ]
Заголовок сообщения: 

Ну, во-первых, TextureImage[0]->data - в данном случае массив из одного элемента.
Во-вторых, это массив не данных, а указателей на данные (см. AUX_RGBImageRec *TextureImage[1];).
Так что его лучше в процессе выполнения не изменять, а то еще потеряешь указатель на важный кусок памяти(картинки)
В-третьих, если хочешь модифицировать то, на что этот указатель указывает, (картинку) то все будет зависеть от выбранного тобой типа представления данных. Ты выбрал GL_RGB и GL_UNSIGNED_BYTE. Следовательно, логично предположить: чтобы изменить ту область памяти, на которую указывает TextureImage[0]->data, необходимо использовать что-то вроде:
Код:
long x, y; // координаты точки, кот. ты хочешь изменить
long xmax; // ширина изображения
TextureImage[0]->data[(xmax*y+x)*3    ]=something; // красная составляющая (R)
TextureImage[0]->data[(xmax*y+x)*3 + 1]=something; // зеленая составляющая (G)
TextureImage[0]->data[(xmax*y+x)*3 + 2]=something; // синяя   составляющая (B)

P.S. По поводу кода не уверен так как под рукой нет ни glaux.h, ни вообще VC++...

Автор:  gkv311 [ 06 июн 2007 03:17 ]
Заголовок сообщения: 

Вроде бы читать у меня получается.
Но вот беда - не знаю как создать временный (конечный) массив для текстуры (ну точнее для рисунка, который я потом загружу как текстуру)
Я прочитал про:
GLubyte tempTex[128][128][3];

При таком "раскладе" всё загружается нормально. Ну например:
Код:
GLubyte tempTex[128][128][3];
                for (int i = 0; i < 128; i++)
                {
                    for (int j = 0; j < 128; j++)
                    {
                        tempTex[i][j][0]=(GLubyte)255;
                        tempTex[i][j][1]=(GLubyte)100;
                        tempTex[i][j][2]=(GLubyte)0;
                    }
                }

Но попытки увеличить размер до 1024x1024 приводят к тому, что программа вылетает при объявлении GLubyte tempTex[1024][1024][3];

Я что-то в принципе не правильно делаю/понимаю??

Автор:  MagicWolf [ 06 июн 2007 09:28 ]
Заголовок сообщения: 

tempTex[1024][1024][3] - размещает в статической памяти, попробуй выделить динамически:
tempTex = malloc(1024*1024*3);

Автор:  gkv311 [ 06 июн 2007 14:22 ]
Заголовок сообщения: 

Блин, никак не могу разобраться, как создать динамический массив...
Если я пробую так, то есть пытаюсь создать полную аналогию статического 3хмерного массива, который выводит на экран ТО что я задал:
Код:
int tempTexRes = 256;
GLubyte*** tempTex  = new GLubyte**[tempTexRes];
for (int i = 0; i < tempTexRes; i++)
{
    tempTex[i] = new GLubyte*[tempTexRes];
    for (int j = 0; j < tempTexRes; j++) tempTex[i][j] = new GLubyte[3];
}

  for (int i = 0; i < tempTexRes; i++)
                {
                    for (int j = 0; j < tempTexRes; j++)
                    {
                        tempTex[i][j][0]=(GLubyte)255;
                        tempTex[i][j][1]=(GLubyte)100;
                        tempTex[i][j][2]=(GLubyte)0;
                    }
                }

то прога вылетает при
glTexImage2D(GL_TEXTURE_2D, 0, 3, tempTexRes, tempTexRes, 0, GL_RGB, GL_UNSIGNED_BYTE, tempTex);

Поэтому я создал одномерный динамический вот так:
Код:
        int tempTexRes = 1024;
        GLubyte* tempTex  = new GLubyte[tempTexRes*tempTexRes*3];
        for (int i = 0; i < tempTexRes; i++)
        {
             for (int j = 0; j < tempTexRes; j++)
             {
                 tempTex[tempTexRes*3*i + 3*j + 0] = (GLubyte)5;
                 tempTex[tempTexRes*3*i + 3*j + 1] = (GLubyte)255;
                 tempTex[tempTexRes*3*i + 3*j + 2] = (GLubyte)5;
             }
        }


Теперь буду думать дальше ;-)
Нет ни у кого хорошой ссылки с объяснением алгоритмов обработки картинки, например resize алгоритмом lanczos, hermite и иже с ними?...[/code][/quote]

Автор:  MagicWolf [ 07 июн 2007 14:21 ]
Заголовок сообщения: 

Тебе надо выделять просто 1024*1024*3 байтов. Непрерывно. А ты выделяешь и указатели под массивы! Их и glTexImage2D не понимает.

А вот "одномерный динамический" - это правильно.

resize - не интересовался :oops:

Автор:  gkv311 [ 07 июн 2007 20:01 ]
Заголовок сообщения: 

Вобщем зря я эти массивы изучал...
Я думал, что проблема возникает при создании текстуры, но похоже:
Код:
AUX_RGBImageRec *LoadBMP(char *Filename)            // Loads A Bitmap Image
{
   FILE *File=NULL;                           // File Handle

   if (!Filename)                              // Make Sure A Filename Was Given
   {return NULL; }                           // If Not Return NULL

   File=fopen(Filename,"r");                     // Check To See If The File Exists
   if (File)                                 // Does The File Exist?
   {
      fclose(File);                           // Close The Handle
      return auxDIBImageLoad(Filename);            // Load The Bitmap And Return A Pointer
   }
   return NULL;                              // If Load Failed Return NULL
}


...эта функция по-любому криво читает BMP нехорошего разрешения.
Поскольку мой ресайз ничего толкового не вывел на экран :-(

Поэтому ноги в руки и я пришёл к неплохому консольному конвертеру nConverter (XnView). Он может и ресайзить, как душе угодно... Хотя lanczoc работает смртельно медленно...

Возникла другая проблема. Для оптимизации загрузки нового файла мне надо не прерывая конвейер поменять на ходу (ко времени, когда она будет готова) новую текстуру. Заставить не ждать nConverter и получить когда картинка будет готова у меня получилось, но на этапе
Код:
   AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture
   memset(TextureImage,0,sizeof(void *)*1);   // Set The Pointer To NULL

   if (TextureImage[0]=LoadBMP(strTemp))
   {
      Status=TRUE;
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
   }

у меня возникает критическая (хоть и Очень маленькая) задержка (мне она очень мешает).
Есть предложения как её можно запаралеллить, не заставляя конвеер ждать, или это невозможно???

Автор:  MagicWolf [ 08 июн 2007 13:03 ]
Заголовок сообщения: 

Посмотри: Урок 35. Проигрывание AVI файлов в OpenGL.
// Обновление текстуры

glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, 256, 256, GL_RGB, GL_UNSIGNED_BYTE, data);

Автор:  gkv311 [ 09 июн 2007 04:00 ]
Заголовок сообщения: 

Про glTexSubImage2D я уже видел, но только я не знал как ей правильно пользоваться :o
Но покапался и всё получилось :D
Теперь у меня текстура меняется ПЛАВНО сверху вниз. Это действительно сильно помогает...

Страница 1 из 1 Часовой пояс: UTC + 3 часа [ Летнее время ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/