Difference between revisions of "Texturing a Sphere"

From OpenGL.org
Jump to: navigation, search
m (Again, use glGenLists instead of just assigning a random value to the display list. For good programming.)
(Cubemapping a Sphere: Adding GLSL version)
Line 5: Line 5:
 
Load a cubemap as shown in [[Common_Mistakes#Creating_a_Cubemap_Texture|Creating a Cubemap Texture]]<br>
 
Load a cubemap as shown in [[Common_Mistakes#Creating_a_Cubemap_Texture|Creating a Cubemap Texture]]<br>
 
Let's assume that we'll be using shaders. If you haven't learned shaders yet, now is the time.<br>
 
Let's assume that we'll be using shaders. If you haven't learned shaders yet, now is the time.<br>
This code is in GLSL. The vertex shader :
+
This code is in GLSL 1.10. The vertex shader :
 +
<source lang="c">
 +
  //[VERTEX SHADER]
 +
  #version 110
 
   uniform mat4 ProjectionModelviewMatrix;
 
   uniform mat4 ProjectionModelviewMatrix;
 
   varying vec3 TexCoord0;
 
   varying vec3 TexCoord0;
Line 13: Line 16:
 
     TexCoord0 = gl_Normal;
 
     TexCoord0 = gl_Normal;
 
   }
 
   }
 +
</source>
  
 
The fragment shader. Notice that the normal has been copied to TexCoord0 and this will be used to sample the cubemap.
 
The fragment shader. Notice that the normal has been copied to TexCoord0 and this will be used to sample the cubemap.
 +
<source lang="c">
 +
  //[FRAGMENT SHADER]
 +
  #version 110
 
   uniform samplerCube Texture0;
 
   uniform samplerCube Texture0;
 
   varying vec3 TexCoord0;
 
   varying vec3 TexCoord0;
Line 22: Line 29:
 
     gl_FragColor = texel;
 
     gl_FragColor = texel;
 
   }
 
   }
 +
</source>
  
 
==2D Texture Mapping a Sphere==
 
==2D Texture Mapping a Sphere==

Revision as of 07:52, 21 April 2012

Let's assume you want to create something that looks like the planet earth. You want to apply a map of the earth to a sphere.
There are 2 ways to texture a sphere. Either by applying a cubemap or either by applying a 2D texture. For best result, use a cubemap. The problem with applying a 2D texture is that when you wrap a 2D texture onto a sphere, the top and bottom area of the sphere, the texture looks squeezed.

Cubemapping a Sphere

Load a cubemap as shown in Creating a Cubemap Texture
Let's assume that we'll be using shaders. If you haven't learned shaders yet, now is the time.
This code is in GLSL 1.10. The vertex shader :

  //[VERTEX SHADER]
  #version 110
  uniform mat4 ProjectionModelviewMatrix;
  varying vec3 TexCoord0;
  void main()
  {
     gl_Position = ProjectionModelviewMatrix * gl_Vertex;
     TexCoord0 = gl_Normal;
  }

The fragment shader. Notice that the normal has been copied to TexCoord0 and this will be used to sample the cubemap.

  //[FRAGMENT SHADER]
  #version 110
  uniform samplerCube Texture0;
  varying vec3 TexCoord0;
  void main()
  {
     vec4 texel = textureCube(Texture0, TexCoord0);
     gl_FragColor = texel;
  }

2D Texture Mapping a Sphere

Either you need to write your own code to create a sphere and you compute the texcoords yourself or you use another library like GLU or glhlib.

GLU

C

 GLUquadricObj *sphere=NULL;
 sphere = gluNewQuadric();
 gluQuadricDrawStyle(sphere, GLU_FILL);
 gluQuadricTexture(sphere, TRUE);
 gluQuadricNormals(sphere, GLU_SMOOTH);
 //Making a display list
 mysphereID = glGenLists(1);
 glNewList(mysphereID, GL_COMPILE);
 gluSphere(sphere, 1.0, 20, 20);
 glEndList();
 gluDeleteQuadric(sphere);
 //-----------------
 //and whenever you want to render, call glCallList(mysphereID)
 //to kill the display list, glDeleteLists(mysphereID, 1);

Java

 Texture earth;
 try {
   earth = TextureIO.newTexture(new File(dataPath("EarthMap_2500x1250.jpg")), true);
 }
 catch (IOException e) {    
   javax.swing.JOptionPane.showMessageDialog(null, e);
 }
 GLUQuadric sphere = new GLUQuadric();
 gluQuadricDrawStyle(sphere, GLU_FILL);
 gluQuadricTexture(sphere, true);
 gluQuadricNormals(sphere, GLU_SMOOTH);
 //Making a display list
 mysphereID = glGenLists(1);
 glNewList(mysphereID, GL_COMPILE);
 earth.enable();
 earth.bind();
 gluSphere(sphere, 1000.0, 20, 20);
 earth.disable();
 glEndList();
 gluDeleteQuadric(sphere);
 //-----------------
 //and whenever you want to render, call glCallList(mysphereID)
 //to kill the display list, glDeleteLists(mysphereID, 1);

GLHLIB

If you want to use glhlib http://sourceforge.net/projects/glhlib/
The header file glhlib.h explains how to use :

 glhSphereObject2 Sphere;
 memset(&Sphere, 0, sizeof(glhSphereObject2));
 Sphere.RadiusA=1.0;
 Sphere.RadiusB=1.0;
 Sphere.RadiusC=1.0;
 Sphere.Stacks=10;
 Sphere.Slices=10;
 Sphere.IndexFormat=GLH_INDEXFORMAT_16BIT;
 Sphere.VertexFormat=GLHVERTEXFORMAT_VNT;
 Sphere.TexCoordStyle[0]=1;
 Sphere.ScaleFactorS[0]=Sphere.ScaleFactorT[0]=1.0;
 //-----------------
 glhCreateSpheref2(&Sphere);
 //-----------------
 //HOW TO RENDER (You might want to use VBO, I'm just using VA here):
 glBindTexture(GL_TEXTURE_2D, TextureID);
 //-----------------
 glVertexPointer(3, GL_FLOAT, sizeof(GLHVertex_VNT), Sphere.pVertex);
 uint mypointer=(uint)Sphere.pVertex;
 mypointer+=12;
 glNormalPointer(GL_FLOAT, sizeof(GLHVertex_VNT), (uint *)mypointer);
 mypointer+=12;
 glTexCoordPointer(2, GL_FLOAT, sizeof(GLHVertex_VNT), (uint *)mypointer);
 glDrawRangeElements(GL_TRIANGLES, Sphere.Start_DrawRangeElements, Sphere.End_DrawRangeElements, Sphere.TotalIndex, GL_UNSIGNED_SHORT, Sphere.pIndex16Bit);
 //.........and delete it when your program closes
 glhDeleteSpheref2(Sphere);