Anyone has a link to a nice tutorial or some code for sphere texture mapping? Only part of the sky texture is being mapped onto the sphere when am trying to make a sky.
Easiest is to create the sphere in a modeler like 3ds Max, and apply the texturing you want in there.
Second easiest is to map the X/Z coordinates to the U/V texture coordinates (a planar mapping), assuming Y is up. This will give some stretching at the horizon, though.
Third easiest is to apply a spherical mapping. You have to create the sphere geometry youself to do this. Here’s some code that does just that (in Java, you can translate):
static final VertexBuffer makeVertexBuffer(GLWrap gl, float radius, int slices, int wedges) throws Exception {
byte[] data = new byte[(slices + 1) * (wedges + 1) * 32];
ByteBuffer bb = ByteBuffer.wrap(data);
bb.order(ByteOrder.nativeOrder());
bb.rewind();
for (int slice = 0; slice <= slices; ++slice) {
float v = slice / (float) slices;
float y = (float) Math.sin(Math.PI * (v - 0.5f));
float r = 1.0f - y * y;
if (r < 0) r = 0;
r = (float) Math.sqrt(r);
for (int wedge = 0; wedge <= wedges; ++wedge) {
float u = wedge / (float) wedges;
float phi = (float) Math.PI * (u * 2 - 1);
float x = (float) Math.sin(phi) * r;
float z = (float) Math.cos(phi) * r;
assert Math.abs(x * x + y * y + z * z - 1) < 1e-5;
bb.putFloat(x * radius);
bb.putFloat(y * radius);
bb.putFloat(z * radius);
bb.putFloat(x);
bb.putFloat(y);
bb.putFloat(z);
bb.putFloat(u);
bb.putFloat(v);
}
}
bb.flip();
return new VertexBuffer(Scene.Usage.Static, data, VertexChannel.PositionNormalTexCoord);
}
static final VertexBuffer makeIndexBuffer(GLWrap gl, int slices, int wedges) throws Exception {
byte[] data = new byte[slices * wedges * 6 * 2];
int max = (slices + 1) * (wedges + 1);
ByteBuffer bb = ByteBuffer.wrap(data);
bb.order(ByteOrder.nativeOrder());
bb.rewind();
for (int slice = 0; slice < slices; ++slice) {
int base = slice * (wedges + 1);
int secondBase = (slice + 1) * (wedges + 1);
assert secondBase + 1 < max;
for (int wedge = 0; wedge < wedges; ++wedge) {
bb.putShort((short) base);
bb.putShort((short) (base + 1));
bb.putShort((short) (secondBase + 1));
bb.putShort((short) (secondBase + 1));
bb.putShort((short) (secondBase));
bb.putShort((short) base);
++base;
++secondBase;
}
}
bb.flip();
return new VertexBuffer(Scene.Usage.Static, data, VertexChannel.Index);
}
Thanks!