Difference between revisions of "Texturing a Sphere"

From OpenGL Wiki
Jump to: navigation, search
(Cubemapping a Sphere: Adding GLSL version)
m (Remove extraneous "either")
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
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.<br>
 
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.<br>
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.<br>
+
There are 2 ways to texture a sphere. Either by applying a cubemap or 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.<br>
 
<br>
 
<br>
 
==Cubemapping a Sphere==
 
==Cubemapping a Sphere==
Line 6: Line 6:
 
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 1.10. The vertex shader :
 
This code is in GLSL 1.10. The vertex shader :
<source lang="c">
+
 
 +
<source lang="glsl">
 
   //[VERTEX SHADER]
 
   //[VERTEX SHADER]
 
   #version 110
 
   #version 110
Line 19: Line 20:
  
 
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">
+
 
 +
<source lang="glsl">
 
   //[FRAGMENT SHADER]
 
   //[FRAGMENT SHADER]
 
   #version 110
 
   #version 110
Line 35: Line 37:
 
===GLU===
 
===GLU===
 
====C====
 
====C====
 +
<source lang="c">
 
   GLUquadricObj *sphere=NULL;
 
   GLUquadricObj *sphere=NULL;
 
   sphere = gluNewQuadric();
 
   sphere = gluNewQuadric();
Line 49: Line 52:
 
   //and whenever you want to render, call glCallList(mysphereID)
 
   //and whenever you want to render, call glCallList(mysphereID)
 
   //to kill the display list, glDeleteLists(mysphereID, 1);
 
   //to kill the display list, glDeleteLists(mysphereID, 1);
 +
</source>
  
 
====Java====
 
====Java====
 +
<source lang="java">
 
   Texture earth;
 
   Texture earth;
 
   try {
 
   try {
Line 74: Line 79:
 
   //and whenever you want to render, call glCallList(mysphereID)
 
   //and whenever you want to render, call glCallList(mysphereID)
 
   //to kill the display list, glDeleteLists(mysphereID, 1);
 
   //to kill the display list, glDeleteLists(mysphereID, 1);
 +
</source>
  
 
===GLHLIB===
 
===GLHLIB===
 
If you want to use glhlib http://sourceforge.net/projects/glhlib/<br>
 
If you want to use glhlib http://sourceforge.net/projects/glhlib/<br>
 
The header file glhlib.h explains how to use :
 
The header file glhlib.h explains how to use :
 +
<source lang="c">
 
   glhSphereObject2 Sphere;
 
   glhSphereObject2 Sphere;
 
   memset(&Sphere, 0, sizeof(glhSphereObject2));
 
   memset(&Sphere, 0, sizeof(glhSphereObject2));
Line 104: Line 111:
 
   //.........and delete it when your program closes
 
   //.........and delete it when your program closes
 
   glhDeleteSpheref2(Sphere);
 
   glhDeleteSpheref2(Sphere);
 +
</source>
  
 
[[Category:Rendering Techniques]]
 
[[Category:Rendering Techniques]]

Latest revision as of 15:46, 20 October 2015

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 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("[http://www.oera.net/How2/PlanetTexs/EarthMap_2500x1250.jpg 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);