Features of OpenGL in wxWidgets (textures do not work)

Questions about wxWidgets running on MS.NET, mono or Portable.NET ? Ask it here !
Post Reply
KilloN
In need of some credit
In need of some credit
Posts: 1
Joined: Tue Jun 26, 2012 11:18 am

Features of OpenGL in wxWidgets (textures do not work)

Post by KilloN »

Hello, everybody. Previously my applications were written solely for the Spanish. GLUT. However, having decided that it is obsolete decided to switch to wxWidgets!!!

I have everything working except for one thing, does not want to show the texture! Though you shit, the whole Net break, I did not change the current code. So the main question, why do not display the texture. Although the version of GLUT had no such problems? :?: :?: :?:

Example code:
A. The button downloads the texture:
[spoiler]

Code: Select all

void gameInterface::onOpenClick( wxCommandEvent& event )
{
  wxString caption = wxT("Открыть файл");
  wxString wildcard =
    wxT("Файлы рисунков (*.tga,*.jpeg,*.png,*.bmp)|*.tga;*.jpeg;*.png;*.bmp|TGA файлы (*.tga)|*.tga|JPEG файлы (*.jpeg)|*.gpeg|PNG файлы (*.png)|*.png|BMP файлы (*.bmp)|*.bmp");
  wxString defaultDir = wxT("\Pictures");
  wxString defaultFilename = wxEmptyString;

  wxFileDialog dialog(NULL, caption, defaultDir, defaultFilename,
    wildcard, wxID_OPEN);
  if (dialog.ShowModal() == wxID_OK){
    GLuint* IDt = wxLoadImage(dialog.GetPath());
    if(IDt){
      if(PAR::TexImage != NULL)  
        glDeleteTextures(1, PAR::TexImage);
      PAR::TexImage = IDt;
      m_statusBar1->SetLabelText(wxT("Рисунок успешно загружен!"));
    }
  }

}

[/spoiler]

At first I thought that maybe I have it wrong ship, but I used 3 razdnyh function. Including the one I used in the GLUT version (can only load TGA files)
Taken my function:
[spoiler]

Code: Select all

GLuint* wxLoadImage(wxString path){

  GLuint* ID=new GLuint[1];
  glGenTextures( 1, &ID[0] );
  
  glBindTexture( GL_TEXTURE_2D, *ID );
  
  // the first time, init image handlers (remove this part if you do it somewhere else in your app)
  static bool is_first_time = true;
  if(is_first_time)
  {
    wxInitAllImageHandlers();
    
    is_first_time = false;
  }
  
  // check the file exists
  if(!wxFileExists(path))
  {
    wxMessageBox( _("Failed to load resource image") );
    exit(1);  
  }
    
  wxImage* img=new wxImage( path );
  
  int imageWidth=img->GetWidth();
  int imageHeight=img->GetHeight();

  int textureWidth;
  int textureHeight;
  
  glPixelStorei(GL_UNPACK_ALIGNMENT,   1   );
  
    /*
     * Many graphics card require that textures be power of two.
     * Below is a simple implementation, probably not optimal but working.
     * If your texture sizes are not restricted to power of 2s, you can
     * of course adapt the bit below as needed.
     */
    
  float power_of_two_that_gives_correct_width=std::log((float)imageWidth)/std::log(2.0);
  float power_of_two_that_gives_correct_height=std::log((float)imageHeight)/std::log(2.0);
  
        // check if image dimensions are a power of two
        if( (int)power_of_two_that_gives_correct_width == power_of_two_that_gives_correct_width &&
            (int)power_of_two_that_gives_correct_height == power_of_two_that_gives_correct_height)
        {
                // note: must make a local copy before passing the data to OpenGL, as GetData() returns RGB 
                // and we want the Alpha channel if it's present. Additionally OpenGL seems to interpret the 
                // data upside-down so we need to compensate for that.
                GLubyte *bitmapData=img->GetData();
                GLubyte *alphaData=img->GetAlpha();
 
                int bytesPerPixel = img->HasAlpha() ?  4 : 3;
 
                int imageSize = imageWidth * imageHeight * bytesPerPixel;
                GLubyte *imageData=new GLubyte[imageSize];
 
                int rev_val=imageHeight-1;
 
                for(int y=0; y<imageHeight; y++)
                {
                        for(int x=0; x<imageWidth; x++)
                        {
                                imageData[(x+y*imageWidth)*bytesPerPixel+0]=
                                        bitmapData[( x+(rev_val-y)*imageWidth)*3];
 
                                imageData[(x+y*imageWidth)*bytesPerPixel+1]=
                                        bitmapData[( x+(rev_val-y)*imageWidth)*3 + 1];
 
                                imageData[(x+y*imageWidth)*bytesPerPixel+2]=
                                        bitmapData[( x+(rev_val-y)*imageWidth)*3 + 2];
 
                                if(bytesPerPixel==4) imageData[(x+y*imageWidth)*bytesPerPixel+3]=
                                        alphaData[ x+(rev_val-y)*imageWidth ];
                        }//next
                }//next
 
                // if yes, everything is fine
                glTexImage2D(GL_TEXTURE_2D,
                             0,
                             bytesPerPixel,
                             imageWidth,
                             imageHeight,
                             0,
                             img->HasAlpha() ?  GL_RGBA : GL_RGB,
                             GL_UNSIGNED_BYTE,
                             imageData);
 
                textureWidth  = imageWidth;
                textureHeight = imageHeight;
 
                delete [] imageData;
        }
  else // texture is not a power of two. We need to resize it
  {
    
    int newWidth=(int)std::pow( 2.0, (int)(std::ceil(power_of_two_that_gives_correct_width)) );
    int newHeight=(int)std::pow( 2.0, (int)(std::ceil(power_of_two_that_gives_correct_height)) );
    
    //printf("Unsupported image size. Recommand values: %i %i\n",newWidth,newHeight);   
    
    GLubyte  *bitmapData=img->GetData();
    GLubyte        *alphaData=img->GetAlpha();
    
    int old_bytesPerPixel = 3;
    int bytesPerPixel = img->HasAlpha() ?  4 : 3;
    
    int imageSize = newWidth * newHeight * bytesPerPixel;
    GLubyte  *imageData=new GLubyte[imageSize];
    
    int rev_val=imageHeight-1;
    
    for(int y=0; y<newHeight; y++)
    {
      for(int x=0; x<newWidth; x++)
      {
        
        if( x<imageWidth && y<imageHeight ){
          imageData[(x+y*newWidth)*bytesPerPixel+0]=
          bitmapData[( x+(rev_val-y)*imageWidth)*old_bytesPerPixel + 0];
          
          imageData[(x+y*newWidth)*bytesPerPixel+1]=
            bitmapData[( x+(rev_val-y)*imageWidth)*old_bytesPerPixel + 1];
          
          imageData[(x+y*newWidth)*bytesPerPixel+2]=
            bitmapData[( x+(rev_val-y)*imageWidth)*old_bytesPerPixel + 2];
          
          if(bytesPerPixel==4) imageData[(x+y*newWidth)*bytesPerPixel+3]=
            alphaData[ x+(rev_val-y)*imageWidth ];
          
        }
        else
        {
          
          imageData[(x+y*newWidth)*bytesPerPixel+0] = 0;
          imageData[(x+y*newWidth)*bytesPerPixel+1] = 0;
          imageData[(x+y*newWidth)*bytesPerPixel+2] = 0;
          if(bytesPerPixel==4) imageData[(x+y*newWidth)*bytesPerPixel+3] = 0;
        }
        
      }//next
    }//next
    
    // set texture parameters as you wish
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // GL_LINEAR
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // GL_LINEAR

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    
    glTexImage2D(GL_TEXTURE_2D,
           0,
           img->HasAlpha() ?  4 : 3,
           newWidth,
           newHeight,
           0, 
           img->HasAlpha() ?  GL_RGBA : GL_RGB, 
           GL_UNSIGNED_BYTE,
           imageData);
    
    textureWidth=newWidth;
    textureHeight=newHeight;
    
    delete [] imageData;
  }
  

  
  return ID;
  
}
[/spoiler]

I altered the function:
[spoiler]

Code: Select all

GLuint* wxLoadImage(wxString path){

  GLuint* ID=new GLuint[1];
  // хотим построить текстуры в i-м элементе массива (указать OpenGL на доступную память)
  glGenTextures( 1, &ID[0] );
  
  // Создание текстуры
  glBindTexture( GL_TEXTURE_2D, *ID );    // определяем тип построенной текст-ры (2D текстура) (создание текстуры, кот. будет сохранена в этой памяти)
  
  // Проверка правильности пути(сущ. файла)
  if(!wxFileExists(path))  {
    wxMessageBox( _("Не удалось загрузить изображение") );
    return NULL;  
  }
    
  wxImage* img=new wxImage( path );
  
  int imageWidth=img->GetWidth();
  int imageHeight=img->GetHeight();
  int bytesPerPixel = img->HasAlpha() ?  4 : 3;
  
  // ф-я управляет хранением пикселей, устанавливаем параметр выравнивания всех строк развертки
  glPixelStorei(GL_UNPACK_ALIGNMENT,   1   );
  
    // Многие видеокарты требуют, чтобы текстура была степенью двойки.
  float power_of_two_that_gives_correct_width=std::log((float)imageWidth)/std::log(2.0);
  float power_of_two_that_gives_correct_height=std::log((float)imageHeight)/std::log(2.0);
  bool step2 = (int)power_of_two_that_gives_correct_width == power_of_two_that_gives_correct_width &&
    (int)power_of_two_that_gives_correct_height == power_of_two_that_gives_correct_height;
  
  GLubyte *imageData;
  GLubyte *bitmapData=img->GetData();
  GLubyte *alphaData=img->GetAlpha();
  // Только если нет альфа канала, т.к. GetData не возвращает альфа канал

  if(step2 && alphaData==NULL) {
    imageData = img->GetData();
    goto toEnd;
  }

  int imageSize = imageWidth * imageHeight * bytesPerPixel;
  imageData = new GLubyte[imageSize];;

  int rev_val=imageHeight-1;

    // проверяем, является ли изображение степенью двойки
  int x,y;
    if(step2){

    for(y=0; y<imageHeight; y++){
      for(x=0; x<imageWidth; x++){

        imageData[(x+y*imageWidth)*bytesPerPixel+0]=
          bitmapData[( x+(rev_val-y)*imageWidth)*3];

        imageData[(x+y*imageWidth)*bytesPerPixel+1]=
          bitmapData[( x+(rev_val-y)*imageWidth)*3 + 1];

        imageData[(x+y*imageWidth)*bytesPerPixel+2]=
          bitmapData[( x+(rev_val-y)*imageWidth)*3 + 2];

        imageData[(x+y*imageWidth)*bytesPerPixel+3]=
          alphaData[ x+(rev_val-y)*imageWidth ];
      }//next
    }//next
  } else {
    // Новые размеры текстыры
    int newWidth=(int)std::pow( 2.0, (int)(std::ceil(power_of_two_that_gives_correct_width)) );
    int newHeight=(int)std::pow( 2.0, (int)(std::ceil(power_of_two_that_gives_correct_height)) );
    
    for(y=0; y<imageHeight; y++){
      for(x=0; x<imageWidth; x++){

        imageData[(x+y*newWidth)*bytesPerPixel+0]=
          bitmapData[( x+(rev_val-y)*imageWidth)*3 + 0];

        imageData[(x+y*newWidth)*bytesPerPixel+1]=
          bitmapData[( x+(rev_val-y)*imageWidth)*3 + 1];

        imageData[(x+y*newWidth)*bytesPerPixel+2]=
          bitmapData[( x+(rev_val-y)*imageWidth)*3 + 2];

        if(bytesPerPixel==4) imageData[(x+y*newWidth)*bytesPerPixel+3]=
          alphaData[ x+(rev_val-y)*imageWidth ];
      }
    }

    for(y = imageHeight; y<newHeight; y++){
      for(x = imageWidth; x<newWidth; x++){

        imageData[(x+y*newWidth)*bytesPerPixel+0] = 0;
        imageData[(x+y*newWidth)*bytesPerPixel+1] = 0;
        imageData[(x+y*newWidth)*bytesPerPixel+2] = 0;
        if(bytesPerPixel==4) imageData[(x+y*newWidth)*bytesPerPixel+3] = 0;

      }//next
    }//next
    imageWidth = newWidth;
    imageHeight= newHeight;
  }//if

toEnd:

  glTexImage2D(GL_TEXTURE_2D,
    0,
    bytesPerPixel,
    imageWidth,
    imageHeight,
    0, 
    img->HasAlpha() ?  GL_RGBA : GL_RGB, 
    GL_UNSIGNED_BYTE,
    imageData);

  delete [] imageData;
  
  return ID;
}
[/spoiler]

рабочая функция c TGA файлами:
[spoiler]

Code: Select all


#include <iostream>
#include <fstream>
// Структурная инфо о файле TGA
using namespace std;
#pragma pack(push,1)
struct TGAHEADER {
  GLbyte  identsize;              // размер ID field that follows header (0)
    GLbyte  colorMapType;           // 0 = None, 1 = paletted
    GLbyte  imageType;              // 0 = none, 1 = индекс, 2 = rgb, 3 = серый, +8=rle  // RLE - кодирование длин серий(метод сжатия)
    unsigned short  colorMapStart;          // First colour map entry
    unsigned short  colorMapLength;         // Number of colors
    unsigned char   colorMapBits;      // bits per palette entry
    unsigned short  xstart;                 // image x origin
    unsigned short  ystart;                 // image y origin
    unsigned short  width;                  // ширина в пикселях
    unsigned short  height;                 // высота в пикселях
    GLbyte  bits;                   // количество бит на пиксель (8 16, 24, 32)
    GLbyte  descriptor;             // дескриптор рисунка
};// TGAHEADER
#pragma pack(pop)


// ф-я загрузки текстур
GLbyte * bLoadTGA(const char *fileName, GLint *iWidth, GLint *iHeight, GLint *iComponents, GLenum *eFormat) {
    ifstream  iFile;        // ссылка на тип файла
    TGAHEADER tgaHeader;    // TGA file header
    unsigned long lImageSize;  // размер текстуры в байтах
    GLbyte  *pBits = NULL;      // ссылка на биты данных

  // Открытие файла
iFile.open(fileName,ios::in | ios::binary);
  if(!iFile.is_open()){
    cout<<"Невозможно открыть файл";
        return NULL;
  }
  // Запись структуры TGA (binary)
  // &tgaHeader - указатель на область данных в которую записываются данные, считанные из файла
  // 18/* sizeof(TGAHEADER)*/ - количество байтов
  // 1 - количество блоков, считываемых при чтении
  // iFile - указатель на открытый файл
    //fread(&tgaHeader, 18/* sizeof(TGAHEADER)*/, 1, iFile);
  iFile.read((char *) &tgaHeader,sizeof(TGAHEADER));

  // Получаем ширину и высоту текстуры
    *iWidth = tgaHeader.width;
    *iHeight = tgaHeader.height;
    *eFormat = GL_BGR_EXT;      // формат информации о текселях
    *iComponents = GL_RGB8;      // внутренний формат данных изображения 

  lImageSize = tgaHeader.width * tgaHeader.height * tgaHeader.bits / 8; // ширина * высота * кол. байтов

  // Динамическое выделение памяти
    pBits = new GLbyte [lImageSize]; // возвр. указатель на первый бит выделенной памяти
    if(pBits == NULL)
        return NULL;
    
    // Запись битов текстуры из файла в выделеную память
  iFile.read((char *) pBits, lImageSize);
    if( pBits == NULL){
        delete [] pBits;  // освобождаем выделенную память
        return NULL;    // ошибка
        }

     // Устанавливаем формат OpenGL для пикселей
    switch(tgaHeader.bits)
        {
        case 24:     
            *eFormat = GL_BGR_EXT;
            *iComponents = GL_RGB8;
            break;
        case 32:
            *eFormat = GL_BGRA_EXT;
            *iComponents = GL_RGBA8;
            break;
        case 8:
            *eFormat = GL_LUMINANCE;
            *iComponents = GL_LUMINANCE8;
            break;
        };

  // закрытие файла
    iFile.close();
        
    // возвращаем биты данных
    return pBits;
}
[/spoiler]

Finally rendenga function and initialization:
[spoiler]

Code: Select all


#include "GameGLPane.h"

static const int cColumns  = 5;      // количество колонок
static const int cRows    = 5;      // количество строк

GameGLPane::GameGLPane(gameInterface *canvas, int* args) :
wxGLCanvas(canvas, wxID_ANY,  wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas"),  args){

  dColumns  = 1.0f / cColumns;
  dRows    = 1.0f / cRows;

  //SetCurrent(*canvas);

  //glEnable(GL_DEPTH_TEST);          // включение теста глубины (удаление скрытых поверхностей)
  glClearColor(0.0f,0.0f,0.0f,1.0f);      // установка цвета и значения альфа, исп при очистке буф. цвета
  glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);      // установка режима растеризации

  glEnable(GL_TEXTURE_2D);//*/

  glTexEnvf(GL_TEXTURE_ENV,    // определяемая текстурная среда
    GL_TEXTURE_ENV_MODE,  // определяемое имя параметра
    GL_REPLACE);  // знач-е пар-ра: значения текселей замещают коды геометрических фрагментов

  // Установка параметров текстуры
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // GL_LINEAR
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // GL_LINEAR

  // Задаём способ обработки координат s текстуры не попадающей в диапазон от 0 до 1
  //glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);

  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);


};

void GameGLPane::Render(wxPaintEvent& evt){
  
  wxGLCanvas::SetCurrent();
  wxPaintDC(this);

  //glViewport(0,0,400,400);        // устанавливаем поле просотра с размерами окна
  
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0.0,1.0,0.0,1.0);

  glMatrixMode(GL_MODELVIEW);
  // загрузка единичной матрицы
  glLoadIdentity();

  // очистка буферов 
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

  glColor3f(1.0f,1.0f,0.0f);

  if(PAR::TexImage==NULL) goto toEnd;
  
  // Рисуем
  glBindTexture(GL_TEXTURE_2D, PAR::TexImage[0]);  // выбираем текстуру

  glBegin(GL_QUADS);
    glTexCoord2f(1.0f, 0.0f); glVertex2f(0.0f, 0.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex2f(0.0f, 1.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex2f(1.0f, 1.0f);
    glTexCoord2f(0.0f, 0.0f); glVertex2f(1.0f, 0.0f);
  glEnd();

  /*float dR1 = 0.0f;
  float dR2;
  float dC1 = 0.0f;
  float dC2;
  glBegin(GL_QUADS);
  for (int j =1;j<=cRows;j++){
    dR2 = j*dRows;
    for(int i = 1;i<=cColumns;i++){
      dC2 = i*dColumns;
      glTexCoord2f(dR1, dC1); glVertex2f(dR1, dC1);
      glTexCoord2f(dR1, dC2); glVertex2f(dR1, dC2);
      glTexCoord2f(dR2, dC2); glVertex2f(dR2, dC2);
      glTexCoord2f(dR2, dC1); glVertex2f(dR2, dC1);
      dC1 = dC2;
    }
    dR1 = dR2;
    dC1 = 0.0f;
  }
  glEnd();//*/

toEnd:
  glFlush();  //опорожнить все очереди команд и буферы OpenGL
  SwapBuffers();
}

void GameGLPane::mouseDown(wxMouseEvent& event){
  int x =10;
};

void GameGLPane::Resized(wxSizeEvent& evt)
{
  wxGLCanvas::OnSize(evt);

  Refresh();
}
[/spoiler]

n just a square with no texture is displayed and all: (((
Interesting thread who would understand what was happening, because I thought dried up, threw the Muse!

P.S. Sorry for the English Google translation :)))

files Project (MVS 10)
http://files.mail.ru/H1YKGE
sampei
In need of some credit
In need of some credit
Posts: 1
Joined: Tue May 28, 2013 4:17 pm

Re: Features of OpenGL in wxWidgets (textures do not work)

Post by sampei »

I have the same issue everything is working except for the textures ... not sure what could be causing the problem :?:

Suggestions?


___________
Cheers!
Post Reply