forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   SDL+Open GL загрузка участка текстуры (http://forum.boolean.name/showthread.php?t=9109)

aureli0 09.09.2009 19:59

SDL+Open GL загрузка участка текстуры
 
Я использую для загрузки текстуры из файла вот такую функцию. Автор не я, поэтому не все с ней ясно(( Главное что хоть работает))

Код:

//Функция загрузки текстур из файла в переменную
bool load(string file, GLuint &tex)
 {
  SDL_Surface *temp = NULL;
  GLint maxTexSize;
  GLuint glFormat = GL_RGBA;
     
  if(file.substr(file.length()-3,3).compare("jpg") == 0)
  {
    glFormat = GL_RGB;
  }
     
  glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);

  temp = IMG_Load(file.data());

  if(temp == NULL)
  {
    cout << "Texture manager ERROR: " << file << " : "<< SDL_GetError() << endl;
    SDL_FreeSurface( temp );
    return 0;
  }
     
  if(temp->w > maxTexSize)
  {
    cout << "Texture manager ERROR: " << file << " texturesize too large." << endl;
  }
 
  glGenTextures(1, &tex);
  glBindTexture(GL_TEXTURE_2D, tex);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );

  glTexImage2D(GL_TEXTURE_2D, 0, glFormat, temp->w, temp->h, 0, glFormat, GL_UNSIGNED_BYTE, temp->pixels);
  SDL_FreeSurface( temp );

  return 1;
}

Можно ли ее как нибудь модифицировать чтобы грузить не всю текстуру целиком, а кусок из нее с вершинами x1,y1 ,x2,y2?

jimon 09.09.2009 20:19

Ответ: SDL+Open GL загрузка участка текстуры
 
aureli0
можно или уже из OpenGL текстуры кусок скопировать в другую текстуру, или перед загрузкой в OpenGL скопировать кусок памяти в другой кусок памяти, но первое лучше :)

aureli0 09.09.2009 21:06

Re: SDL+Open GL загрузка участка текстуры
 
эээ, прости я мало понимаю без примера кода((

bool load(string file, GLuint &tex)
{

...
...

GLuint temp_tex;//временная переменная всей картинки из файла внутри функции

glGenTextures(1, &temp_tex);
glBindTexture(GL_TEXTURE_2D, temp_tex);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );

glTexImage2D(GL_TEXTURE_2D, 0, glFormat, temp->w, temp->h, 0, glFormat, GL_UNSIGNED_BYTE, temp->pixels);
SDL_FreeSurface( temp );

glGenTextures(1, &tex);//генерируем кусок текстуры
glBindTexture(GL_TEXTURE_2D, tex);
...
каким-то магическим образом передаем кусок изображения в эту текстуру
...
}
только как это изображение туда передать то, понятно что скорее всего через текстурные координаты, но в коде это как должно выглядеть?

alcoSHoLiK 09.09.2009 23:31

Ответ: SDL+Open GL загрузка участка текстуры
 
Есть функция glTexSubImage2D. Для нее надо будет вырезать из массива пикселей исходного изображения нужную тебе часть в отдельный массив и передать его в качестве последнего параметра.

Другой вариант, создать одну текстуру, но для разных спрайтов использовать кастомные текстурные координаты.
Если есть текстура размером (width, height), а тебе надо натянуть на спрайт фрагмент с координатами диагонали (x1, y1) и (x2, y2), причем x2 > x1 и y2 > y1, то текстурные координаты расчитываются следующим образом:
Код:

float s_min = x1 / width;
float s_max = x2 / width;
float t_min = y1 / height;
float t_max = y2 / height;

tex_coords[0] = s_min; tex_coords[1] = t_max;
tex_coords[2] = s_min; tex_coords[3] = t_min;
tex_coords[4] = s_max; tex_coords[5] = t_max;
tex_coords[6] = s_max; tex_coords[7] = t_min;

// ...

glBindTexture(GL_TEXTURE_2D, ...);

glVertexPointer(...);
glTexCoordPointer(2, GL_FLOAT, 0, tex_coords);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

Порядок следования s_min, s_max, t_min и t_max может быть другим, в зависимости от того, как ты задаешь координаты вершин. А их вычисление от этого порядка не зависит.

aureli0 14.09.2009 22:08

Re: SDL+Open GL загрузка участка текстуры
 
спасибо:) правда я сделал немного по другому, хотя в целом тоже самое:
Код:

//рисуем затекстурированый полигон из общей текстуры
void _DrawTXT (float W,//размеры всей текстуры
              float H,
              float t_x,//координаты верхнего левого угла в текстуре
              float t_y,
              float t_dx,//размеры куска текстуры
              float t_dy,

              float x,
              float y,
              float dX,
              float dY,
              float delta,//угол поворота
              int center)
 {
    glLoadIdentity();
    glTranslatef(x,y,0); 
    glRotatef(delta,0,0,-1);
    if (center==1) {glTranslatef(-dX/2,-dY/2,0);}//смещаем по центре

    glBegin( GL_QUADS );
        // Верхний левый угол
        glTexCoord2f((t_x/W),(t_y/H));      glVertex2f( 0, 0 );
        //Нижний левый угол
        glTexCoord2f((t_x/W),((t_y+t_dy)/H));  glVertex2f( 0, dY );
        //Нижний правый угол
        glTexCoord2f(((t_x+t_dx)/W),((t_y+t_dy)/H));  glVertex2f( dX, dY );
        //Верхний правый угол
        glTexCoord2f(((t_x+t_dx)/W), (t_y/H) );  glVertex2f( dX, 0 );
    glEnd();

  glLoadIdentity();

 }



Часовой пояс GMT +4, время: 15:04.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot