Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 20

Thread: Texture on a sphere

  1. #1
    Junior Member Newbie
    Join Date
    Nov 2009
    Posts
    11

    Texture on a sphere

    Hi, I have a problem applying a texture to a sphere.
    In the setup phase I do this:
    Code :
    	earth = gluNewQuadric();
     
    	gluQuadricTexture( earth, GL_TRUE);
     
    	earthTexture = LoadBitmap("data/EarthTexture.bmp");
    And when I draw the I use this code
    Code :
    	    glEnable ( GL_TEXTURE_2D );
    	    glBindTexture ( GL_TEXTURE_2D, earthTexture);
    	    gluSphere( earth, 0.9, 36, 72);
    	  glDisable ( GL_TEXTURE_2D );

    But something goes wrong and I obtain this http://yfrog.com/14screenshot20091119at105j

    What am I doing wrong?

    If I try to move the sphere the result is getting even worst.

  2. #2
    Junior Member Newbie
    Join Date
    Nov 2009
    Posts
    11

    Re: Texture on a sphere

    If I try to draw only the texture on a square it works, but if I try to draw the texture on the square after I call the gluSphere also the image on the square is screwed :-(

  3. #3
    Member Regular Contributor
    Join Date
    Mar 2007
    Location
    CA
    Posts
    408

    Re: Texture on a sphere

    The image mapped on the sphere appears like it is rotated 90. Can you rotate your image 90 degrees in some image editor and try again. Is LoadBitmap() a custom function or winOS library function?

    Do you have some code affecting the texture Matrix ie do you call the following somewhere in your code?
    Code :
    glMatrixMode(GL_TEXTURE);

  4. #4
    Junior Member Newbie
    Join Date
    Nov 2009
    Posts
    11

    Re: Texture on a sphere

    Thanks for your answer. I never use the matrix mode GL_TEXTURE explicitly, is there any GL command that makes that matrix change?

    The code for the load bitmap was found on internet and it is this:
    Code :
    int LoadBitmap(char *filename)
    {
        FILE * file;
        char temp;
        long i;
     
        BITMAPINFOHEADER infoheader;
     
        GLuint num_texture;
     
        if( (file = fopen(filename, "rb"))==NULL) return (-1); // Open the file for reading
     
        fseek(file, 18, SEEK_CUR);  /* start reading width & height */
        fread(&infoheader.biWidth, sizeof(int), 1, file);
     
        fread(&infoheader.biHeight, sizeof(int), 1, file);
     
        fread(&infoheader.biPlanes, sizeof(short int), 1, file);
        if (infoheader.biPlanes != 1) {
    	    printf("Planes from %s is not 1: %u\n", filename, infoheader.biPlanes);
    	    return 0;
        }
     
        // read the bpp
        fread(&infoheader.biBitCount, sizeof(unsigned short int), 1, file);
        if (infoheader.biBitCount != 24) {
          printf("Bpp from %s is not 24: %d\n", filename, infoheader.biBitCount);
          return 0;
        }
     
        fseek(file, 24, SEEK_CUR);
     
        // read the data
        if(infoheader.biWidth<0){
    	infoheader.biWidth = -infoheader.biWidth;
        }
        if(infoheader.biHeight<0){
    	infoheader.biHeight = -infoheader.biHeight;
        }
        infoheader.data = (char *) malloc(infoheader.biWidth * infoheader.biHeight * 3);
        if (infoheader.data == NULL) {
    	    printf("Error allocating memory for color-corrected image data\n");
    	    return 0;
        }
     
        if ((i = fread(infoheader.data, infoheader.biWidth * infoheader.biHeight * 3, 1, file)) != 1) {
    	    printf("Error reading image data from %s.\n", filename);
    	    return 0;
        }
     
        for (i=0; i<(infoheader.biWidth * infoheader.biHeight * 3); i+=3) { // reverse all of the colors. (bgr -> rgb)
    	    temp = infoheader.data[i];
    	    infoheader.data[i] = infoheader.data[i+2];
    	    infoheader.data[i+2] = temp;
        }
     
     
        fclose(file); // Closes the file stream
     
        glGenTextures(1, &amp;num_texture);
        glBindTexture(GL_TEXTURE_2D, num_texture); // Bind the ID texture specified by the 2nd parameter
     
        // The next commands sets the texture parameters
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // If the u,v coordinates overflow the range 0,1 the image is repeated
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // The magnification function ("linear" produces better results)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); //The minifying function
     
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
     
        // Finally we define the 2d texture
        glTexImage2D(GL_TEXTURE_2D, 0, 3, infoheader.biWidth, infoheader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, infoheader.data);
     
        // And create 2d mipmaps for the minifying function
        gluBuild2DMipmaps(GL_TEXTURE_2D, 3, infoheader.biWidth, infoheader.biHeight, GL_RGB, GL_UNSIGNED_BYTE, infoheader.data);
     
        free(infoheader.data); // Free the memory we used to load the texture
     
        return (num_texture); // Returns the current texture OpenGL ID
    }

  5. #5
    Junior Member Newbie
    Join Date
    Nov 2009
    Posts
    11

    Re: Texture on a sphere

    I tried to rotate the texture, but it doesn't help

  6. #6
    Member Regular Contributor
    Join Date
    Mar 2007
    Location
    CA
    Posts
    408

    Re: Texture on a sphere

    Mhhm, the glMatrixMode(GL_TEXTURE) question was a remote possibility because you can affect texture coordinates with glTranslate/glRotate etc with it. So it is good to rule that out right away.

    I am surprised rotating the image 90 degrees did nothing.

    Some versions of openGL don't accept non-power of two sizes ie what are the actual values of infoheader.biWidth and infoheader.biHeight? If they are not 64, 128,256 ... 2^integer then try scaling your image file to the nearest power of 2 before loadBMP called.

  7. #7
    Junior Member Newbie
    Join Date
    Nov 2009
    Posts
    11

    Re: Texture on a sphere

    Do you think this may be a problem? If I load the texture on a square it works, so the loader should be ok. Isn't it?

  8. #8
    Junior Member Newbie
    Join Date
    Nov 2009
    Posts
    11

    Re: Texture on a sphere

    What is really weird is that when I load just the square is drawn correctly, while if I load bot the square and the sphere also the texture on the square is messed up

  9. #9
    Member Regular Contributor
    Join Date
    Mar 2007
    Location
    CA
    Posts
    408

    Re: Texture on a sphere

    I wrote a quick code (attached below) to see if I could replicate your problem. It works fine for me. I don't know what your code is doing differently -- maybe looking at the attachment will help you.

    p.s. My windows.h defined BITMAPINFOHEADER and it did NOT have a member named .data so I had to replace everywhere "infoheader.data" with "infoheader_data" of type "unsigned char *". Also note that this forced change from your code which used (char *) malloc to (unsigned char *) malloc.

    Code :
    #include <windows.h>
    #include <stdio.h>
    #include <GL/glut.h>
    #include <math.h>
     
    float anglex = 35;
    float angley = -35;
    float anglez = 0;
    float locZ = 0.0;
    float locY = 0.0;
    float locX = 0.0;
     
    GLUquadric *earth;
    GLuint earthTexture;
     
    int LoadBitmap(char *filename)
    {
        FILE * file;
        char temp;
        long i;
     
        BITMAPINFOHEADER infoheader;
        unsigned char *infoheader_data;
     
        GLuint num_texture;
     
        if( (file = fopen(filename, "rb"))==NULL) return (-1); // Open the file for reading
     
        fseek(file, 18, SEEK_CUR);  /* start reading width & height */
        fread(&amp;infoheader.biWidth, sizeof(int), 1, file);
     
        fread(&amp;infoheader.biHeight, sizeof(int), 1, file);
     
        fread(&amp;infoheader.biPlanes, sizeof(short int), 1, file);
        if (infoheader.biPlanes != 1) {
          printf("Planes from %s is not 1: %u\n", filename, infoheader.biPlanes);
          return 0;
        }
     
        // read the bpp
        fread(&amp;infoheader.biBitCount, sizeof(unsigned short int), 1, file);
        if (infoheader.biBitCount != 24) {
          printf("Bpp from %s is not 24: %d\n", filename, infoheader.biBitCount);
          return 0;
        }
     
        fseek(file, 24, SEEK_CUR);
     
        // read the data
        if(infoheader.biWidth<0){
      infoheader.biWidth = -infoheader.biWidth;
        }
        if(infoheader.biHeight<0){
      infoheader.biHeight = -infoheader.biHeight;
        }
        infoheader_data = (unsigned char *) malloc(infoheader.biWidth * infoheader.biHeight * 3);
        if (infoheader_data == NULL) {
          printf("Error allocating memory for color-corrected image data\n");
          return 0;
        }
     
        if ((i = fread(infoheader_data, infoheader.biWidth * infoheader.biHeight * 3, 1, file)) != 1) {
          printf("Error reading image data from %s.\n", filename);
          return 0;
        }
     
        for (i=0; i<(infoheader.biWidth * infoheader.biHeight * 3); i+=3) { // reverse all of the colors. (bgr -> rgb)
          temp = infoheader_data[i];
          infoheader_data[i] = infoheader_data[i+2];
          infoheader_data[i+2] = temp;
        }
     
     
        fclose(file); // Closes the file stream
     
        glGenTextures(1, &amp;num_texture);
        glBindTexture(GL_TEXTURE_2D, num_texture); // Bind the ID texture specified by the 2nd parameter
     
        // The next commands sets the texture parameters
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // If the u,v coordinates overflow the range 0,1 the image is repeated
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // The magnification function ("linear" produces better results)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); //The minifying function
     
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
     
        // Finally we define the 2d texture
        glTexImage2D(GL_TEXTURE_2D, 0, 3, infoheader.biWidth, infoheader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, infoheader_data);
     
        // And create 2d mipmaps for the minifying function
        gluBuild2DMipmaps(GL_TEXTURE_2D, 3, infoheader.biWidth, infoheader.biHeight, GL_RGB, GL_UNSIGNED_BYTE, infoheader_data);
     
        free(infoheader_data); // Free the memory we used to load the texture
     
        return (num_texture); // Returns the current texture OpenGL ID
    }
     
    void keyboard(unsigned char key, int x, int y)
    {
       switch (key) {
          case 27:
             exit(0);            
             break;
          case 'a':
             anglex+=5;
             break;
          case 'A':
             anglex-=5;
             break;
          case 's':
             angley-=5;
             break;
          case 'S':
             angley+=5;
             break;
          case 'd':
             anglez+=5;
             break;
          case 'D':
             anglez-=5;
             break;
          case 'u':
             locZ-=0.05;
             break;
          case 'U':
             locZ+=0.05;
             break;
          case 'k':
             locY+=0.05;
             break;
          case 'j':
             locY-=0.05;
             break;
          case 'l':
             locX+=0.05;
             break;
          case 'h':
             locX-=0.05;
             break;
          default:
             break;
       }
       glutPostRedisplay();
    }
     
    void display(void)
    {
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
     
       glEnable ( GL_TEXTURE_2D );
       glBindTexture ( GL_TEXTURE_2D, earthTexture);
     
       glMatrixMode(GL_MODELVIEW);
       glLoadIdentity();
       //rotate/translate entire scene with a,A,s,S,D,D and h,l,j,k,u,U keys
       glRotatef(anglez,0.0,0.0,1.0);
       glRotatef(angley,0.0,1.0,0.0);
       glRotatef(anglex,1.0,0.0,0.0);
     
       //draw textured sphere
       glPushMatrix();
          glTranslatef(locX,locY,locZ);
          glScalef(0.5,0.5,0.5);
          gluSphere( earth, 0.9, 36, 72);
       glPopMatrix();
     
       //draw textured rectangle
       glPushMatrix();
          glTranslatef(0.0,0.0,1.0);
          glScalef(0.5,0.5,0.5);
          glBegin(GL_POLYGON);
            glTexCoord2f(0.0, 0.0);
            glVertex2f( -1.0,-1.0);
            glTexCoord2f(1.0, 0.0);
            glVertex2f(  1.0,-1.0);
            glTexCoord2f(1.0, 1.0);
            glVertex2f(  1.0, 1.0);
            glTexCoord2f(0.0, 1.0);
            glVertex2f( -1.0, 1.0);
            glTexCoord2f(0.0, 0.0);
            glVertex2f( -1.0,-1.0);
          glEnd();
       glPopMatrix();
     
       glDisable ( GL_TEXTURE_2D );
     
       glutSwapBuffers();
    }
     
    void init (void) 
    {
      glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
     
      glEnable(GL_DEPTH_TEST);
     
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(-1.0, 1.0, -1.0, 1.0, -2.0, 2.0);
     
      earth = gluNewQuadric();
      gluQuadricTexture( earth, GL_TRUE);
      earthTexture = LoadBitmap("data/EarthTexture.bmp");
    }
     
    int main(int argc, char** argv)
    {
       glutInit(&amp;argc, argv);
       glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
       glutCreateWindow ("Testing Texture");
       init ();
       glutDisplayFunc(display); 
       glutKeyboardFunc(keyboard);
       glutMainLoop();
       return 0; 
    }

  10. #10
    Junior Member Newbie
    Join Date
    Nov 2009
    Posts
    11

    Re: Texture on a sphere

    Thanks again for your reply, I really appreciate it.

    It now maps the texture in the correct way, but if I move there is still an issue. The texture mapping sometimes goes wrong and what I can see is the mirrored texture on the other side rather than the actual texture I'd like to see.

    If you want I can attach the image I am using.
    I am also running my program on Linux.

    Thanks again for your help

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •