PDA

View Full Version : texture mapping skydome



Adrian Hooper
03-12-2009, 08:41 AM
I've created a hemisphere with the following code :

list = gl.glGenLists(1);
int radius = 1060;
final double deg_to_rad = Math.PI / 180;
final double rad_to_deg = 180 / Math.PI;

double x, y, z;

//gl.glPolygonMode (GL.GL_FRONT_AND_BACK, GL.GL_LINE);


gl.glNewList(list, GL.GL_COMPILE);
for (double phi = 0.0; phi <= 80.0; phi += 10.0) {
gl.glBegin(GL.GL_QUAD_STRIP);
for (double theta = -180.0; theta <= 180.0; theta += 10.0) {
x = radius * Math.sin(Math.PI/180 * theta) * Math.cos(Math.PI/180 * phi);
y = radius * Math.cos(Math.PI/180 * theta) * Math.cos(Math.PI/180 * phi);
z = radius * Math.sin(Math.PI/180 * phi);

gl.glVertex3d (x,y,z);
x = radius * Math.sin(Math.PI/180 * theta) * Math.cos(Math.PI/180 * (phi + 10.0));
y = radius * Math.cos(Math.PI/180 * theta) * Math.cos(Math.PI/180 * (phi + 10.0));
z = radius * Math.sin(Math.PI/180 * (phi + 10.0));
gl.glVertex3d (x,y,z);
}
gl.glEnd();
}
gl.glEndList();

This seems to work and creates a hemisphere (slightly strangely though) and now I want to texture it to display my sky image.

I've used a number of things to try and it is texturing it, but very strangely :(

gl.glBindTexture(GL.GL_TEXTURE_2D, textures[0]);
gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE,GL.GL_SPHERE_MAP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
gl.glCallList(list);

I'm using this to bind the texture but it seems to be repeating the texture thousands of times in tiny segments rather than wrapping it around. How can I do it?

Thanks

And sorry, it's using JOGL rather than pure openGL but I can convert between the two

trinitrotoluene
03-12-2009, 11:28 AM
In the code you have posted above, I do not see calls for glTexCoord2f to set texture coordinates. You must choose the right formula to generate texture coordinates. For example to generate s and t coordinates for the texture, you can reuse some part of the computation required for the x and y coordinates of your vertex.



s = (Math.sin(Math.PI/180 * theta) * Math.cos(Math.PI/180 * phi) + 1.0) * 0.5; // Stay s in the range [0.0 1.0] to avoid texture repeat
or simpler
s = (Math.cos(Math.PI/180 * theta) + 1.0) * 0.5;

t = (Math.cos(Math.PI/180 * theta) * Math.cos(Math.PI/180 * phi) + 1.0) *0.5 ; // Stay t in the range [0.0 1.0] to avoid texture repeat
or simpler
t = (Math.cos(Math.PI/180 * phi) + 1.0) *0.5;



So now before each call to glVertex3d you need to call glTexCoord2d(s,t);. Maybe you can also modify your texture wrapping mode to GL_CLAMP_TO_EDGE. I have not tested this code so maybe it will not work right away, but I think this should give you some idea.

Adrian Hooper
03-15-2009, 12:27 AM
Ok I've added that code for s and t, and added it a second time for my second vertex drawing line, but it hasn't seemed to greatly effect the render? I then changed the TexParameteri lines to use the clap to line and it changed the render but is still wrong. The dome now goes a bluey colour all over, the very bottom is completely white, and the line between the blue and the white shows some of the image. So i'm confused.

gl.glBindTexture(GL.GL_TEXTURE_2D, textures[0]);
gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE,GL.GL_SPHERE_MAP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
gl.glCallList(list);



gl.glBegin(GL.GL_QUAD_STRIP);
for (double theta = -180.0; theta <= 180.0; theta += 10.0) {
x = radius * Math.sin(Math.PI/180 * theta) * Math.cos(Math.PI/180 * phi);
y = radius * Math.cos(Math.PI/180 * theta) * Math.cos(Math.PI/180 * phi);
z = radius * Math.sin(Math.PI/180 * phi);

s = (Math.sin(Math.PI/180 * theta) * Math.cos(Math.PI/180 * phi) + 1.0) * 0.5;
t = (Math.cos(Math.PI/180 * theta) * Math.cos(Math.PI/180 * phi) + 1.0) *0.5 ;
gl.glTexCoord2d(s,t);
gl.glVertex3d (x,y,z);

x = radius * Math.sin(Math.PI/180 * theta) * Math.cos(Math.PI/180 * (phi + 10.0));
y = radius * Math.cos(Math.PI/180 * theta) * Math.cos(Math.PI/180 * (phi + 10.0));
z = radius * Math.sin(Math.PI/180 * (phi + 10.0));

s = (Math.sin(Math.PI/180 * theta) * Math.cos(Math.PI/180 * (phi+10.0)) + 1.0) * 0.5;
t = (Math.cos(Math.PI/180 * theta) * Math.cos(Math.PI/180 * phi) + 1.0) *0.5 ;
gl.glTexCoord2d(s,t);
gl.glVertex3d (x,y,z);
}
gl.glEnd();

Thanks