PDA

View Full Version : cant correctly texture a sphere



u-bar
05-01-2006, 02:13 PM
well,
http://img.photobucket.com/albums/v231/no-uname-available-damnit/snaps-ogl5.jpg http://img.photobucket.com/albums/v231/no-uname-available-damnit/snaps-ogl4.jpg

as you see, the texture is distoreted when i translate the sphere around.
the thing is, in another test, trying to solve this, i tried making the sphere rotate, and the texture it self stayed stationary while the spere was clearly rotating (you could see the edges of the faces of the sphere as they when aroung the edge of the sphere).
can someone please help me?

if anybody is interested:


void Widget::initializeGL(){


GLfloat pos[] = { 0.0, 0.0, 0.0, 1.0};
GLfloat spec[] = { 1.0, 1.0, 1.0, 0.0};
GLfloat diff[] = { 1.0, 1.0, 1.0, 0.0};
GLfloat amb[] = { 1.0, 1.0, 1.0, 0.0};
GLfloat shine[] = { 50.0 };

glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shine);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb);
glLightfv(GL_LIGHT0, GL_POSITION, pos);

glClearColor(0.0,0.0,0.0,0.0);
glEnable(GL_DEPTH_TEST);
// glEnable(GL_LIGHTING);
// glEnable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_NORMALIZE);
glDepthFunc(GL_LEQUAL);

buff = QImage();
if(buff.load("earth.png") == NULL){
QMessageBox::critical(this, "Error", "Cannot load texture image");
}
im = QImage();
im = convertToGLFormat(buff);

sun = gluNewQuadric();
glGenTextures(1, &text[0]);
glBindTexture(GL_TEXTURE_2D, text[0]);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

gluBuild2DMipmaps(GL_TEXTURE_2D, 3, im.width(), im.height(), GL_RGBA, GL_UNSIGNED_BYTE, im.bits());
gluQuadricDrawStyle(sun, GLU_FILL);
gluQuadricTexture(sun, GL_TRUE);

}

void Widget::resizeGL(int w, int h){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(0.0,0.0,0.0,0.0,0.0,0.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0,0,w,h);
}

void Widget::paintGL(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, text[0]);
gluQuadricNormals(sun, GL_FLAT);
gluQuadricOrientation(sun, GLU_OUTSIDE);

gluSphere(sun, 0.5, 32.0, 20.0);
glPopMatrix();
renderText(10,10,"Moshe");
//glRotatef(rot++, 0.5, 0.5, 0.0); // That constant rotation i was talking about
update();
}

jide
05-01-2006, 03:02 PM
What update is censed to do ?

Try this but I cannot ensure it:


glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

glLoadIdentity();
glRotatef(rot++, 0.5, 0.5, 0.0);
glBindTexture(GL_TEXTURE_2D, text[0]);
gluQuadricNormals(sun, GL_FLAT);
gluQuadricOrientation(sun, GLU_OUTSIDE);
gluSphere(sun, 0.5, 32.0, 20.0);
update();

u-bar
05-01-2006, 03:06 PM
the update function is for the rotation, i causes the widget to update, displaying the new context of opengl.

and as for the code, still the same...

zed
05-02-2006, 01:24 AM
what youre doing will not work, as a rectangle texture will not fit onto a sphere without some distortion.
there many different ways of texturing a sphere
a search on the internet should find a few (perhaps look for ways ppl have used to unwrap the planets globe onto a 2d piece of paper, projection )

charliejay
05-02-2006, 01:33 AM
Try keeping the gluQuadricTexture command, and using a standard 2 dimensional texture showing the "usual" spherical to cylindrical projection of the earth...

u-bar
05-02-2006, 02:35 PM
i alleardy searched the web dosens of time but i couldnt fin anything.
any refrece to something more accurate?

songho
05-02-2006, 03:35 PM
u-bar,
I did similar stuff using GLU quadric sphere object. I used 512x256 rectangle image as a texture. Can you post the earth image?
Here is my screen shot after mapping. (I used GL_SPHERE_MAP same as you did.)
http://songho.ca/tmp/sphere.png

u-bar
05-02-2006, 03:46 PM
youre render is very beautiful...
the original image is from: http://www.celestiamotherlode.net/catalog/earth.php
(the file i downloaded is "4K Earth Surface Map"),
and since its huge and heavy, i reduced it to a 2.2 MB 1590x1295 image using gimp (which i cant upload to any server because of its size :) )

songho
05-02-2006, 10:30 PM
u-bar,
I quess the source of the texture is same as mine, but I still think it is texture problem, not your codes.

Can you try to use it instead if it renders same distortion:
http://songho.ca/tmp/earth.tga

charliejay
05-03-2006, 01:31 AM
quoted from

http://www.csee.umbc.edu/help/C++/opengl/man_pages/html/glu/sphere.html

If texturing is turned on (with gluQuadricTexture), then 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 +y axis, to 0.25 at the +x axis, to 0.5 at the -y axis, to 0.75 at the -x axis, and back to 1.0 at the +y axis.

Having downloaded the image u-bar is referencing, it looks like it's an orthogonal projection from the equator, meaning that the lines of latitude are not regularly spaced, while the lines of longitude are.

That seems as if gluQuadricTexture should work perfectly with this texture, and not sphere mapping, but I'll be interested to see which is correct...

u-bar
05-03-2006, 04:00 AM
oddly enough:
http://img.photobucket.com/albums/v231/no-uname-available-damnit/snaps-ogl6.jpg

does it matter if i use it in .tga format or convert it with making no changes to it, to .jpg?

songho
05-03-2006, 10:37 AM
u-bar,
Try comment out the following lines;
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);

Does the texture has alpha channel? If not, use GL_RGB instead of GL_RGBA in the gluBuild2DMipmaps(). It should be;
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, im.width(), im.height(), GL_RGB, GL_UNSIGNED_BYTE, im.bits());

ADDED:
When you generating mipmaps with gluBuild2DMipmaps(), the image will be scaled to power of 2, before mipmaps are generated. So it is better having original texture with power of 2, for example, 2048x1024 instead of 1590x1295.

u-bar
05-03-2006, 11:25 AM
finally it works!
thank you!
deleting
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
workd fine...