Texturing a Sphere: Difference between revisions
m →Cubemapping a Sphere: copyedit |
m Remove extraneous "either" |
||
(11 intermediate revisions by 3 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 | 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== | ||
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="glsl"> | |||
//[VERTEX SHADER] | |||
#version 110 | |||
uniform mat4 ProjectionModelviewMatrix; | uniform mat4 ProjectionModelviewMatrix; | ||
varying vec3 TexCoord0; | varying vec3 TexCoord0; | ||
Line 13: | Line 17: | ||
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="glsl"> | |||
//[FRAGMENT SHADER] | |||
#version 110 | |||
uniform samplerCube Texture0; | uniform samplerCube Texture0; | ||
varying vec3 TexCoord0; | varying vec3 TexCoord0; | ||
Line 22: | Line 31: | ||
gl_FragColor = texel; | gl_FragColor = texel; | ||
} | } | ||
</source> | |||
==2D Texture Mapping a Sphere== | ==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.<br> | 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.<br> | ||
===GLU=== | |||
====C==== | |||
<source lang="c"> | |||
GLUquadricObj *sphere=NULL; | GLUquadricObj *sphere=NULL; | ||
sphere = gluNewQuadric(); | sphere = gluNewQuadric(); | ||
gluQuadricDrawStyle(sphere, GLU_FILL); | |||
gluQuadricTexture(sphere, TRUE); | gluQuadricTexture(sphere, TRUE); | ||
gluQuadricNormals(sphere, GLU_SMOOTH); | gluQuadricNormals(sphere, GLU_SMOOTH); | ||
//Making a display list | //Making a display list | ||
mysphereID = 1; | mysphereID = glGenLists(1); | ||
glNewList(mysphereID, GL_COMPILE); | glNewList(mysphereID, GL_COMPILE); | ||
gluSphere(sphere, 1.0, 20, 20); | gluSphere(sphere, 1.0, 20, 20); | ||
Line 38: | 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==== | |||
<source lang="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); | |||
</source> | |||
If you want to use glhlib http:// | ===GLHLIB=== | ||
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 67: | 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);