我创建了一个类,使使用立方体贴图变得非常容易。
public class Cubemap implements Disposable {
private final Pixmap[] data = new Pixmap[6];
private int glHandle;
public Cubemap(Pixmap positiveX, Pixmap negativeX, Pixmap positiveY, Pixmap negativeY, Pixmap positiveZ, Pixmap negativeZ) {
set(positiveX, negativeX, positiveY, negativeY, positiveZ, negativeZ);
reload();
}
public Cubemap(FileHandle positiveX, FileHandle negativeX, FileHandle positiveY, FileHandle negativeY, FileHandle positiveZ, FileHandle negativeZ) {
set(positiveX, negativeX, positiveY, negativeY, positiveZ, negativeZ);
reload();
}
public Cubemap(Pixmap cubemap) {
set(cubemap);
reload();
}
public Cubemap(Texture texture){
set(texture);
reload();
}
private void set(Pixmap positiveX, Pixmap negativeX, Pixmap positiveY, Pixmap negativeY, Pixmap positiveZ, Pixmap negativeZ) {
data[0]=positiveX;
data[1]=negativeX;
data[2]=positiveY;
data[3]=negativeY;
data[4]=positiveZ;
data[5]=negativeZ;
}
public void set(Texture texture) {
texture.getTextureData().prepare();
Pixmap pixmap = texture.getTextureData().consumePixmap();
data[0]=pixmap;
data[1]=pixmap;
data[2]=pixmap;
data[3]=pixmap;
data[4]=pixmap;
data[5]=pixmap;
}
private void set(FileHandle positiveX, FileHandle negativeX, FileHandle positiveY, FileHandle negativeY, FileHandle positiveZ, FileHandle negativeZ) {
set(new Pixmap(positiveX), new Pixmap(negativeX), new Pixmap(positiveY), new Pixmap(negativeY), new Pixmap(positiveZ), new Pixmap(negativeZ));
}
//IF ALL SIX SIDES ARE REPRESENTED IN ONE IMAGE
private void set(Pixmap cubemap) {
int w = cubemap.getWidth();
int h = cubemap.getHeight();
for(int i=0; i<6; i++) data[i] = new Pixmap(w/4, h/3, Pixmap.Format.RGB888);
for(int x=0; x<w; x++)
for(int y=0; y<h; y++){
//-X
if(x>=0 && x<=w/4 && y>=h/3 && y<=h*2/3) data[1].drawPixel(x, y-h/3, cubemap.getPixel(x, y));
//+Y
if(x>=w/4 && x<=w/2 && y>=0 && y<=h/3) data[2].drawPixel(x-w/4, y, cubemap.getPixel(x, y));
//+Z
if(x>=w/4 && x<=w/2 && y>=h/3 && y<=h*2/3) data[4].drawPixel(x-w/4, y-h/3, cubemap.getPixel(x, y));
//-Y
if(x>=w/4 && x<=w/2 && y>=h*2/3 && y<=h) data[3].drawPixel(x-w/4, y-h*2/3, cubemap.getPixel(x, y));
//+X
if(x>=w/2 && x<=w*3/4 && y>=h/3 && y<=h*2/3) data[0].drawPixel(x-w/2, y-h/3, cubemap.getPixel(x, y));
//-Z
if(x>=w*3/4 && x<=w && y>=h/3 && y<=h*2/3) data[5].drawPixel(x-w*3/4, y-h/3, cubemap.getPixel(x, y));
}
cubemap.dispose();
}
public void reload() {
glHandle = Gdx.gl20.glGenTexture();
Gdx.gl20.glBindTexture(GL20.GL_TEXTURE_CUBE_MAP, glHandle);
for (int i = 0; i < 6; i++) {
Gdx.gl20.glTexImage2D(GL20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
GL20.GL_RGB, data[i].getWidth(), data[i].getHeight(), 0,
GL20.GL_RGB, GL20.GL_UNSIGNED_BYTE, data[i].getPixels());
}
Gdx.gl20.glTexParameterf(GL20.GL_TEXTURE_CUBE_MAP, GL20.GL_TEXTURE_MAG_FILTER, GL20.GL_LINEAR);
Gdx.gl20.glTexParameterf(GL20.GL_TEXTURE_CUBE_MAP, GL20.GL_TEXTURE_MIN_FILTER, GL20.GL_LINEAR_MIPMAP_LINEAR);
Gdx.gl20.glTexParameteri(GL20.GL_TEXTURE_CUBE_MAP, GL30.GL_TEXTURE_WRAP_R, GL20.GL_CLAMP_TO_EDGE);
Gdx.gl20.glTexParameteri(GL20.GL_TEXTURE_CUBE_MAP, GL20.GL_TEXTURE_WRAP_S, GL20.GL_CLAMP_TO_EDGE);
Gdx.gl20.glTexParameteri(GL20.GL_TEXTURE_CUBE_MAP, GL20.GL_TEXTURE_WRAP_T, GL20.GL_CLAMP_TO_EDGE);
Gdx.gl20.glGenerateMipmap(GL20.GL_TEXTURE_CUBE_MAP);
}
public void bind(int unit){
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0 + unit);
Gdx.gl20.glBindTexture(GL20.GL_TEXTURE_CUBE_MAP, glHandle);
}
@Override
public void dispose(){
for (int i = 0; i < data.length; i++)
data[i].dispose();
if (glHandle != 0) {
Gdx.gl20.glDeleteTexture(glHandle);
glHandle = 0;
}
}
}
在着色器类中使用它:
public class YourShader implements com.badlogic.gdx.graphics.g3d.Shader {
ShaderProgram program;
Cubemap cubemapTex;
...
@Override
public void init() {
...
cubemapTex = new Cubemap(new Pixmap(Gdx.files.internal("cubemap_image.jpg")));
}
@Override
public void begin(Camera camera, RenderContext context) {
program.begin();
...
cubemapTex.bind(0);
program.setUniformi("u_textureCubemap", 0);
...
}
...
@Override
public void dispose() {
if (program != null) {
program.dispose();
program = null;
}
if(cubemapTex!=null){
cubemapTex.dispose();
cubemapTex = null;
}
...
}
}