glBindTexture does not apply texture in GL_QUADS

0

Problem: glBindTexture does not apply texture to "GL_QUADS" when using OPENGL in C ++.

My experience in c ++, and especially in OPENGL is limited, but I relied on in this code . I made a few modifications to make it compatible with my project. Modifications can be seen in the reproduction below.

When testing the original code, I checked that it works. But this modification caused the texture to not be applied. The "GL_QUADS" are created, everything works perfectly except the texture.

NOTE: I looked at some issues related to the subject, here in the "stackoverflow", but the answers were not enough for me. I've still followed a tutorial from Nanyang Technological Uuniversity.

I'm grateful for any help.

bool loadPngImage(char *name, struct pnhImage *img){ //int &outWidth, int &outHeight, bool &outHasAlpha, GLubyte **outData); // TESTADO NO CODIGO ORIGINAL LINK https://gist.github.com/mortennobel/5299151
bool loadTexturePNG(char *filepath, struct pnhImage *img);
void buildQuadradoColorText(char webcolor[7], GLuint tID, float x, float y, float w, float h){;
void desenhar();

bool initGL(int argc, char** argv){  
  glutInit(&argc, argv);                              // Initialize GLUT  
  glutInitDisplayMode(GLUT_DOUBLE);                   // Set double buffered mode
  glutCreateWindow("OpenGL Setup Test");              // Create a window with the given title
  glutInitWindowSize(Tela.width, Tela.height);        // Set the window's initial width & height          
  glutInitWindowPosition(0, 0);                       // Position the window's initial top-left corner
  glutFullScreen();                                   // Exibe em tela cheia  
  glutDisplayFunc(desenhar);                          // Register display callback handler for window re-paint        
  glutReshapeFunc(winResize);                         // Register callback handler for window re-size event    
  glutMouseFunc(mouseEvent);                          // EVENTOS DO MOUSE
  glutMotionFunc(MotionCallback);                     // MONITORA MOVIMENTOS DO MOUSE COM BOTAO ATIVO 
  glutPassiveMotionFunc(passiveMotionCallback);       // MONITORA MOVIMENTO DE MOUSE COM BOTAO INATIVO
  glutSpecialFunc(keyPressEspecial);                  // EVENTOS DE TECLAS ESPECIAIS  
  glutTimerFunc( refreshFrame, Timer, 0);             // First timer call immediately

  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);               // Black and opaque

  glEnable(GL_DEPTH_TEST);
  // The following two lines enable semi transparent
  glEnable(GL_BLEND);
  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  

  glShadeModel(GL_FLAT);   
  glEnable(GL_TEXTURE_2D);

  return true;
}

bool loadTexturePNG(char *filepath, struct pnhImage *img){
  std::cout << "Carregando textura '" << filepath << "' ";     

  // CARREGA O TILE DO SOLO
  if (loadPngImage(filepath, img)){                
    img->tID = 0;

    glEnable(GL_TEXTURE_2D);

    // CRIA UMA TEXTURA OPEGL
    glGenTextures(1, &img->tID );        

    std::cout << ">> tID: '" << img->tID << "' ";        

    // "Bind" a textura recém-criado: todas as funções textura futuras irá modificar esta textura
    glBindTexture(GL_TEXTURE_2D, img->tID);        

    // FORNECE A IMAGEM AO OPNGL
    glTexImage2D( GL_TEXTURE_2D, 
                  0,
                  img->alpha ? 4 : 3, 
                  img->width,
                  img->height, 
                  0, 
                  img->alpha ? GL_RGBA : GL_RGB,
                  GL_UNSIGNED_BYTE,
                  img->data
    ); 

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

    // Quando Ampliar a Imagem (sem mipmap maior disponível), use filtragem LINEAR
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // Quando minifying a imagem, use uma mistura linear de dois mipmaps, cada filtrada linearmente também
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 

    // Gera mipmaps, pelo caminho.
    //glGenerateMipmap(GL_TEXTURE_2D);    

    // APAGAMOS/LIBERAMOS A IMAGE QUE JAH FOI CARREGADA PARA O OPENGL
    //SDL_FreeSurface(img->data);            

    if (glGetError() != GL_NO_ERROR){
      std::cout << "[FALHA]" << std::endl;            
      return false;
    }          

    std::cout << "[OK] " << std::endl;

    glBindTexture(GL_TEXTURE_2D, 0);            

    return true;
  }else
    std::cout << "[FALHA] " << std::endl;

  return false;
}

// X -> LEFT POINT, Y, TOP POINT, W -> WIDTH, H -> HEIGHT
void buildQuadradoColorText(char webcolor[7], GLuint tID, float x, float y, float w, float h){
  struct rgbColor cor = WebColorTORgb(webcolor); // CONVERT HEX TO INT RGB

  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);      

  glColor3f (cor.r, cor.g, cor.b); // ISSO FUNCIONA, E A OMISSAO NAO INTERFERE
  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, tID); 

  // Draw a Red 1x1 Square centered at origin
  glBegin(GL_QUADS);            // Each set of 4 vertices form a quad   
    printf("texture id: %d.\n", tID );

    glTexCoord2f(0  , 0);
    glVertex2f( x   , y   );    // x, y

    glTexCoord2f(1, 0);
    glVertex2f( x+w , y   );

    glTexCoord2f(1, 1);
    glVertex2f( x+w , y-h );     

    glTexCoord2f(0, 1);
    glVertex2f( x   , y-h );                

  glEnd();

  glBindTexture(GL_TEXTURE_2D, 0);  
}

void desenhar(){  
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     // Clear the color buffer (background)          

  glMatrixMode(GL_MODELVIEW);                             // To operate on Model-View matrix
  glLoadIdentity();  

  buildQuadradoColorText((char*)"#24a621", tID, -1, 1, 2, 2);         

  // MANDA O GRAFICO RENDERIZADO PARA A JANELA
  glutSwapBuffers();         
}
    
asked by anonymous 26.09.2016 / 02:37

1 answer

0

I discovered the solution, and the problem was in the loadTexturePNG function. Although I admit that I do not really understand the reason, the build test verified that the changes fixed the problem.

If someone would like to complement explaining why this solution was successful, I am grateful.

  • Replace glTexParameteri with glTexParameterf ;
  • Comment or delete the line:
  • glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    

    Ready, texturing works! See the changed function:

    /* CARREGA UMA IMAGEM PNG DE TEXTURA PARA O OPENGL */
    bool loadTexturePNG(char *filepath, struct pnhImage *img, bool desbind = true){
      std::cout << "Carregando textura '" << filepath << "' ";     
    
      // CARREGA O TILE DO SOLO
      if (loadPngImage(filepath, img)){                
        img->tID = 0;   
    
        // CRIA UMA TEXTURA OPEGL
        glGenTextures(1, &img->tID );        
    
        std::cout << ">> tID: '" << img->tID << "' ";        
    
        // "Bind" a textura recém-criado: todas as funções textura futuras irá modificar esta textura
        glBindTexture(GL_TEXTURE_2D, img->tID);        
    
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    
        // FORNECE A IMAGEM AO OPNGL
        glTexImage2D(
                      GL_TEXTURE_2D, 
                      0,
                      img->alpha ? 4 : 3, 
                      img->width,
                      img->height, 
                      0, 
                      img->alpha ? GL_RGBA : GL_RGB,
                      GL_UNSIGNED_BYTE,
                      img->data
        ); 
    
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
    
        // Quando Ampliar a Imagem (sem mipmap maior disponível), use filtragem LINEAR    
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);                 
    
        // Quando minifying a imagem, use uma mistura linear de dois mipmaps, cada filtrada linearmente também
        //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    
        // Gera mipmaps, pelo caminho.
        //glGenerateMipmap(GL_TEXTURE_2D);    
    
        // APAGAMOS/LIBERAMOS A IMAGE QUE JAH FOI CARREGADA PARA O OPENGL
        //SDL_FreeSurface(img->data);            
    
        if (glGetError() != GL_NO_ERROR){
          std::cout << "[FALHA]" << std::endl;            
          return false;
        }          
    
        std::cout << "[OK] " << std::endl;
    
        if (desbind)
          glBindTexture(GL_TEXTURE_2D, 0);
    
        // LIBERA A IMAGEM DA MEMORIA
        free(img->data);
    
        return true;
      }else
        std::cout << "[FALHA] " << std::endl;
    
      return false;
    }
    
        
    02.10.2016 / 05:35