glBindTexture does not apply texture in GL_QUADS

Asked

Viewed 114 times

0

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

My experience in c++, and mainly in OPENGL is limited, however, I based in this code. I made some few modifications to make it compatible with my project. Modifications can be noted in the reproduction below.

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

NOTE: I noticed some issues related to the subject, here in the "stackoverflow", however, the answers were not enough for me. I still followed a tutorial of Nanyang Technological Uuniversity.

I appreciate 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();         
}
  • 1

    It would be better if you detail what has changed in the code, so it is difficult to know what the problem is. Tip: This code uses Opengl version < 3.1, which no one else recommends using, if you’re just maintaining an existing application, fine. Now if you are creating something new, I strongly recommend that you do using Opengl 3.2+, You can take the first steps from this site: http://open.gl

  • @paulocanedo , thanks for your attention, I am using OPENGL 4.5. Relative to change, what happened was that the original code textured a square directly, I turned it into a loadTexturePNG function, which loads a PNG and indexes to an index using glBindTexture. This allows the same code (function) to be used to load several distinct textures (files), and also allows re-use of texture with glBindTexture + texture ID. That’s what I understand about the operation glBindTexture. So I load Pngs, linking the texture ID, and then reuse them.

  • @paulocaned The goal of creating a function that loads and indexes the textures, is to avoid that every time the window is redesigned, it is necessary to reload the HD file, and still transform it into texture. This would take up unnecessary processing. Texture indices are saved in a struct array for this purpose.

1 answer

0

I found the solution, and the problem was in the function loadTexturePNG. Although I admit I don’t really understand the reason, the build test found that the changes fixed the issue.

In case anyone wants to supplement by explaining why this solution was successful, I am grateful.

  1. Replace glTexParameteri for glTexParameterf;
  2. Comment or delete line:
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

Okay, 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;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.