sunLoadingImage
whowedImag
decoration left 1
decoration left 2
transhome
transprojects
transgallery
transarticles
decoration rigth
English
Українська
Show/Hide search bar
black cat logo variable logo
[21 Січ 2013]

Допоміжні функції для текстур в OpenGL

На цій сторінці зібрані допоміжні функції, які допомагають в роботі з текстурами в OpenGL і Qt. Далі наведено функції для:
  • створення пустої 2D текстури (GL_TEXTURE_2D)
  • завантаження 2D текстури (GL_TEXTURE_2D)
  • завантаження кубічної текстури (GL_TEXTURE_CUBE_MAP)
  • завантаження 3D текстури (GL_TEXTURE_3D)
  • Створення пустої текстури з заданим розміром і параметрами
    GLuint create2DTexture(GLuint width, GLuint height,
                            GLenum internalFormat, GLenum format, GLenum elemType)
    {
       GLint texture;

       glGenTextures(1, &texture);
       glBindTexture(GL_TEXTURE_2D, texture);
       glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width,
                            height, 0, format, elemType, nullptr);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       glGenerateMipmap(GL_TEXTURE_2D);
       glBindTexture(GL_TEXTURE_2D, 0);

       return texture;
    }
    Завантажити 2D текстуру з файла в OpenGL
    // завантаження текстури з файла
    GLuint load2DTexture(const qs & path)
    {
       GLint texture;

       // Завантаження QImage з файла
       QImage imageToConvert;
       if(!imageToConvert.load(path))
       {
          Log::instance().log("Texture2D::load() failed : " + path);
          return;
       }

       // Спробувати перетворити завантажене QImage в OpenGL формат
       QImage GL_formatted_image = QGLWidget::convertToGLFormat(imageToConvert);
       if(GL_formatted_image.isNull())
       {
          Log::instance().log("Texture2D::load() failed to convert : " + path);
          return;
       }

       // створити нову текстуру з завантаженого зображення
       glGenTextures(1, &texture);
       glBindTexture(GL_TEXTURE_2D, texture);
       glTexImage2D(
             GL_TEXTURE_2D,
             0,
             GL_RGBA,
             GL_formatted_image.width(),
             GL_formatted_image.height(),
             0,
             GL_RGBA,
             GL_UNSIGNED_BYTE,
             GL_formatted_image.bits()
          );
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       glGenerateMipmap(GL_TEXTURE_2D);
       glBindTexture(GL_TEXTURE_2D, 0);

       return texture;
    }
    Завантаженя кубічної текстури з файла в OpenGL
    GLuint loadCubeTexture(const qs & path)
    {
       GLint texture;

       // дістати назву файлу та розширення
       qs pre = path.mid(0, path.lastIndexOf());
       qs ext = path.mid(path.lastIndexOf()+1, 3);

       // всі грані кубічної текстури
       GLenum cubesides[6] =
       {
          GL_TEXTURE_CUBE_MAP_POSITIVE_X,
          GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
          GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
          GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
          GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
          GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
       };

       // шляхи до зображень, які відповідають кожній грані куба
       qs cubepaths[6] =
       {
          pre + "_posx." + ext,
          pre + "_negx." + ext,
          pre + "_posy." + ext,
          pre + "_negy." + ext,
          pre + "_posz." + ext,
          pre + "_negz." + ext
       };

       // створити нову текстуру і ініціалізувати параметри
       glGenTextures(1, &texture);
       glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);

       // встановити зображення для кожної грані кубічної текстури
       for(short i=0; i<6; i++)
       {
          QImage imageToConvert;
          if(!imageToConvert.load(cubepaths[i]))
          {
             Log::instance().log("ERROR : Cube face loading failed: " + cubepaths[i]);
             return;
          }

          QImage GL_formatted_image = QGLWidget::convertToGLFormat(imageToConvert);
          if(GL_formatted_image.isNull())
          {
             Log::instance().log("ERROR : Cube face - fail convert: " + path);
             return;
          }

          glTexImage2D(
             cubesides[i],
             0,
             GL_RGBA,
             GL_formatted_image.width(),
             GL_formatted_image.height(),
             0,
             GL_RGBA,
             GL_UNSIGNED_BYTE,
             GL_formatted_image.bits()
             );
       }

       glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);

       glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
       glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

       return texture;
    }
    Завантаження 3D текстури з групи файлів в OpenGL
    // кожен елемент pathes містить шлях до зображення (шару 3D текстури)
    GLuint load3DTexture(const std::vector & pathes)
    {
       GLuint texture;
       if(pathes.size() == 0)
       {
          Log::instance().log("Texture3D::load() - empty array of pathes");
          return texture;
       }

       GLsizei width, height, depth = (GLsizei)pathes.size();

       std::vector formatedImages(pathes.size());

       // завантажити і відформатувати кожне зображення
       {
          for(uint i=0; i       {
             QImage imageToConvert;
             if(!imageToConvert.load(pathes[i]))
             {
                Log::instance().log("Texture3D::load() failed : " + pathes[i]);
                return;
             }

             QImage GL_formatted_image = QGLWidget::convertToGLFormat(imageToConvert);
             if(GL_formatted_image.isNull())
             {
                Log::instance().log("Texture3D::load() failed to
                convert to gl format : " + pathes[i]);
                return;
             }

             formatedImages[i] = GL_formatted_image;

             if(i==0)
             {
                width = formatedImages[i].width();
                height = formatedImages[i].height();
             }
             else
             {
                if(width != formatedImages[i].width()
                      || height != formatedImages[i].height())
                {
                   Log::instance().log("Texture3D::load() failed :
                   different dimensions of images. " + pathes[0] + " " + pathes[i]);
                   return;
                }
             }
          }
       }

       // створити пусту 3D тектуру
       {
          glGenTextures(1, &m_texture);
          glBindTexture(GL_TEXTURE_3D, m_texture);
          glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
          glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
          glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
          glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
          glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

          // виділити необхідну кількість памяті під усі шари
          glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, width,
                height, depth, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
       }

       // скопіювати зображення у відповідні шари 3D текстури
       {
          for(uint i=0; i       {
             glTexSubImage3D(
                   GL_TEXTURE_3D, 0,
                   0, 0, (GLint)i,
                   width, height, 1,
                   GL_RGBA, GL_UNSIGNED_BYTE,
                   formatedImages[i].bits()
             );
          }
       }

       glGenerateMipmap(GL_TEXTURE_3D);
       glBindTexture(GL_TEXTURE_3D, 0);
    }
    Не забудьте видалити текстури:
    glDeleteTextures(1, &texture);


    Sun and Black Cat- Ігор Дихта (igor dykhta email) © 2007-2014