Tuesday, May 29, 2012

Simple method for texture mapping on sphere Using gluSphere and gluQuadricTexture in OpenGL

In my previous article [here] I have shown you how to map texture in solid sphere. In that method whole sphere is render using triangles and providing texture co-ordinates which seems difficult to understand. Now in this article I am going to show you simple method to map texture on Sphere. We first draw a sphere using gluSphere and texture co-ordinates are automatically generated by gluQuadricTexture function for Sphere.
gluSphere:
syntax:
void WINAPI gluSphere( GLUquadric *qobj, GLdouble radius, GLint slices, GLint stacks);


Parameters
qobj
The quadric object (created with gluNewQuadric).
radius
The radius of the sphere.
slices
The number of subdivisions around the z-axis (similar to lines of longitude).
stacks
The number of subdivisions along the z-axis (similar to lines of latitude).
Return value
This function does not return a value.
Remarks
The gluSphere function draws a sphere of the given radius centered around the origin. The sphere is subdivided around the z-axis into slices and along the z-axis into stacks (similar to lines of longitude and latitude).
If the orientation is set to GLU_OUTSIDE (with gluQuadricOrientation), any normals generated point away from the center of the sphere. Otherwise, they point toward the center of the sphere.
If texturing is turned on (with gluQuadricTexture): texture coordinates are generated so that t ranges from 0.0 at z = -radius to 1.0 at z = radius (t increases linearly along longitudinal lines); and s ranges from 0.0 at the positive y-axis, to 0.25 at the positive x-axis, to 0.5 at the negative y-axis, to 0.75 at the negative x-axis, and back to 1.0 at the positive y-axis.
 
gluQuadricTexture:
 
syntax:
void WINAPI gluQuadricTexture( GLUquadric *quadObject, GLboolean textureCoords);
Parameters
quadObject
The quadric object (created with gluNewQuadric).
textureCoords




A flag indicating whether texture coordinates are to be generated. The following values are valid.
Value
GL_TRUE :-Generate texture coordinates.
GL_FALSE :-Do not generate texture coordinates. This is the default value.
Return value
This function does not return a value.
Remarks
The gluQuadricTexture function specifies whether texture coordinates are to be generated for quadrics rendered with quadObject.
The manner in which texture coordinates are generated depends upon the specific quadric rendered.
Here I will show you only source code of main function, complete source code you can download from below.
main.cpp

#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <GL/glut.h>
#include "imageloader.h"

using namespace std;

void handleKeypress(unsigned char key, int x, int y) {
  switch (key) {
    case 27: //Escape key
      exit(0);
  }
}

//Makes the image into a texture, and returns the id of the texture
GLuint loadTexture(Image* image) {
  GLuint textureId;
  glGenTextures(1, &textureId); //Make room for our texture
  glBindTexture(GL_TEXTURE_2D, textureId); //Tell OpenGL which texture to edit
  //Map the image to the texture
  glTexImage2D(GL_TEXTURE_2D,                //Always GL_TEXTURE_2D
         0,                            //0 for now
         GL_RGB,                       //Format OpenGL uses for image
         image->width, image->height,  //Width and height
         0,                            //The border of the image
         GL_RGB, //GL_RGB, because pixels are stored in RGB format
         GL_UNSIGNED_BYTE, //GL_UNSIGNED_BYTE, because pixels are stored
                           //as unsigned numbers
         image->pixels);               //The actual pixel data
  return textureId; //Returns the id of the texture
}

GLuint _textureId; //The id of the textur
GLUquadric *quad;
float rotate;

//GLUquadricObj quad;

void initRendering() {
  glEnable(GL_DEPTH_TEST);
  //glEnable(GL_LIGHTING);
  //glEnable(GL_LIGHT0);
  glEnable(GL_NORMALIZE);
  glEnable(GL_COLOR_MATERIAL);
  quad = gluNewQuadric();

  Image* image = loadBMP("earth.bmp");
  _textureId = loadTexture(image);
  delete image;
}

void handleResize(int w, int h) {
  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0);
}

void drawScene() {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

  glTranslatef(0.0f, 1.0f, -16.0f);

  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, _textureId);

  //Bottom
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glRotatef(90,1.0f,0.0f,0.0f);
  glRotatef(rotate,0.0f,0.0f,1.0f);
  gluQuadricTexture(quad,1);
    gluSphere(quad,2,20,20);

  glutSwapBuffers();
}
void update(int value)
{
    rotate+=2.0f;
    if(rotate>360.f)
    {
        rotate-=360;
    }
    glutPostRedisplay();
    glutTimerFunc(25,update,0);
}
int main(int argc, char** argv) {
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(800, 800);

  glutCreateWindow("Textures-codeincodeblock.blogspot.com");
  initRendering();

   glutTimerFunc(25,update,0);

  glutDisplayFunc(drawScene);
  glutKeyboardFunc(handleKeypress);
  glutReshapeFunc(handleResize);

  glutMainLoop();
  return 0;
}











Project Output is like this


you can download the complete project from here
Download Texture in Sphere.rar

16 comments:

  1. Works perfectly. Awesome.

    ReplyDelete
    Replies
    1. good that you got it..can u please help me how to get past this error??
      "input.open(filename, ifstream::binary);
      assert(!input.fail() || !"Could not find file");"

      Delete
    2. It means your program doesn't found the image file. So keep the image file together with .exe file.

      Delete
    3. Hi i got a error with the rotate variable, it say that is ambigous... any idea?

      Delete
  2. Really superb!! Thank you very much.

    ReplyDelete
  3. Doesn't even run, one error that VS can't even pick up

    ReplyDelete
  4. the code compiles without showing any error. but during run time,this statement gives an error..(imageloader.cpp line 118)
    "input.open(filename, ifstream::binary);
    assert(!input.fail() || !"Could not find file");"
    please help me overcome this problem.

    thanks in advance

    ReplyDelete
    Replies
    1. It means your program doesn't found the image file. So keep the image file together with .exe file.

      Delete
  5. thanks for posting the code here..it helped me out a long way..


    ~cheers from kiran to the admin

    ReplyDelete
  6. THANK YOU!!!!! I have been spending days trying to understand this concept and your code helped me work it through!

    ReplyDelete
  7. Huaaaaa D': It works! well I just take some lines, but it really is work! THANK YOU SOOOO VERY MUCH you kind soul :'D

    ReplyDelete
  8. how do i run the program there are 2 .cpp files.

    ReplyDelete
  9. i got the output, but the image is inverted

    ReplyDelete
  10. can you specify #include"imageloder.h" in detail. or please post its source code

    ReplyDelete
  11. ||=== Build file: "no target" in "no project" (compiler: unknown) ===|
    D:\NOTES\2016\2 - Summer -16\Graphics\texture\earth.o:earth.cpp|| undefined reference to `loadBMP(char const*)'|
    D:\NOTES\2016\2 - Summer -16\Graphics\texture\earth.o:earth.cpp|| undefined reference to `Image::~Image()'|
    ||error: ld returned 1 exit status|
    ||=== Build failed: 3 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|


    these are the errors i have. can someone help me to solve them??

    ReplyDelete