在球体的一半中显示图像

时间:2014-06-04 10:13:58

标签: android image opengl-es panoramas

我想在球体的一半中显示分辨率为4096x2048(这不是球形图像)的图像。我使用panoramagl android库来获取全景视图。在我扩展com.panoramagl.PLIView的活动中,我声明:

    CustomPLSpherical2Panorama cylindricalPanorama = new CustomPLSpherical2Panorama();
    PLImage imageFace = new PLImage(PLUtils.getBitmap(this, R.drawable.spherical_pano), false);
    cylindricalPanorama.setImage(imageFace);
    setPanorama(cylindricalPanorama);

为了不超过最大纹理尺寸1024x1024,我将此图像缩小了2倍。

public class CustomPLSpherical2Panorama extends PLQuadricPanoramaBase {
/**
 * init methods
 */

public CustomPLSpherical2Panorama() {
    super();
}

@Override
protected void initializeValues() {
    super.initializeValues();
    this.setPreviewDivs(PLConstants.kDefaultSphere2PreviewDivs);
    this.setDivs(PLConstants.kDefaultSphere2Divs);
}

/**
 * property methods
 */

@Override
public int getTilesNumber() {
    return 4;
}

@Override
public void setImage(PLIImage image) {
    if (image != null) {
        int w = image.getWidth(), h = image.getHeight();
        image = image.scale(w / 2, h / 2);
        w = image.getWidth();
        h = image.getHeight();
        if (w >= 128 && w <= 2048 && h >= 64 && h <= 1024 && PLMath.isPowerOfTwo(w) && PLMath.isPowerOfTwo(h) && w % h == 0) {
            int w2 = w >> 1, w32 = w2 >> 4;
            PLIImage frontImage = PLImage.crop(image, w2 - w32, 0, w32 << 1, h);
            PLIImage backImage = PLImage.joinImagesHorizontally(PLImage.crop(image, w - w32, 0, w32, h), PLImage.crop(image, 0, 0, w32, h));
            PLIImage leftImage = PLImage.crop(image, 0, 0, w2, h);
            PLIImage rightImage = PLImage.crop(image, w2, 0, w2, h);
            this.setTexture(new PLTexture(frontImage), PLSpherical2FaceOrientation.PLSpherical2FaceOrientationFront.ordinal());
            this.setTexture(new PLTexture(backImage), PLSpherical2FaceOrientation.PLSpherical2FaceOrientationBack.ordinal());
            this.setTexture(new PLTexture(leftImage), PLSpherical2FaceOrientation.PLSpherical2FaceOrientationLeft.ordinal());
            this.setTexture(new PLTexture(rightImage), PLSpherical2FaceOrientation.PLSpherical2FaceOrientationRight.ordinal());
        }
    }
}

/**
 * render methods
 */

@Override
protected void internalRender(GL10 gl, PLIRenderer renderer) {
    PLITexture previewTexture = this.getPreviewTextures()[0];
    PLITexture[] textures = this.getTextures();
    PLITexture frontTexture = textures[PLSpherical2FaceOrientation.PLSpherical2FaceOrientationFront.ordinal()];
    PLITexture backTexture = textures[PLSpherical2FaceOrientation.PLSpherical2FaceOrientationBack.ordinal()];
    PLITexture leftTexture = textures[PLSpherical2FaceOrientation.PLSpherical2FaceOrientationLeft.ordinal()];
    PLITexture rightTexture = textures[PLSpherical2FaceOrientation.PLSpherical2FaceOrientationRight.ordinal()];

    boolean frontTextureIsValid = (frontTexture != null && frontTexture.getTextureId(gl) != 0);
    boolean backTextureIsValid = (backTexture != null && backTexture.getTextureId(gl) != 0);
    boolean leftTextureIsValid = (leftTexture != null && leftTexture.getTextureId(gl) != 0);
    boolean rightTextureIsValid = (rightTexture != null && rightTexture.getTextureId(gl) != 0);

    if (frontTextureIsValid || backTextureIsValid || leftTextureIsValid || rightTextureIsValid || (previewTexture != null && previewTexture.getTextureId(gl) != 0)) {
        gl.glEnable(GL10.GL_TEXTURE_2D);

        GLUquadric quadratic = this.getQuadric();
        float radius = PLConstants.kPanoramaRadius * 10;
        int divs = this.getDivs();
        int halfDivs = this.getDivs() / 2, quarterDivs = halfDivs / 2;

        if (previewTexture != null) {
            if (frontTextureIsValid && backTextureIsValid && leftTextureIsValid && rightTextureIsValid)
                this.removePreviewTextureAtIndex(0, true);
            else {
                int previewDivs = this.getPreviewDivs();
                gl.glBindTexture(GL10.GL_TEXTURE_2D, previewTexture.getTextureId(gl));
                GLUES.gluSphere(gl, quadratic, radius, previewDivs, previewDivs);
            }
        }

        // Front Face
        if (frontTextureIsValid) {
            gl.glBindTexture(GL10.GL_TEXTURE_2D, frontTexture.getTextureId(gl));
            GLUES.glu3DArc(gl, quadratic, PLConstants.kPI8, -PLConstants.kPI16, false, radius, quarterDivs, quarterDivs);
        }

        // Back Face
        if (backTextureIsValid) {
            gl.glBindTexture(GL10.GL_TEXTURE_2D, backTexture.getTextureId(gl));
            GLUES.glu3DArc(gl, quadratic, PLConstants.kPI8, -PLConstants.kPI16, true, radius, quarterDivs, quarterDivs);
        }

        // Left Face
        if (leftTextureIsValid) {
            gl.glBindTexture(GL10.GL_TEXTURE_2D, leftTexture.getTextureId(gl));
            GLUES.gluHemisphere(gl, quadratic, false, radius, halfDivs, halfDivs);
            //GLUES.gluPartialDisk(gl, quadratic, 0, PLConstants.kPI16, quarterDivs, quarterDivs, PLConstants.kPI16, PLConstants.kPI8);
        }

        //Right Face
        if (rightTextureIsValid) {
            gl.glBindTexture(GL10.GL_TEXTURE_2D, rightTexture.getTextureId(gl));
            GLUES.gluHemisphere(gl, quadratic, true, radius, halfDivs, halfDivs);
        }

        gl.glDisable(GL10.GL_TEXTURE_2D);
    }
}

}

上面的代码帮助我在球体中显示我的图像,但问题是图像不是球形的,因此它在球体的底部和顶部伸展得太多。

针对该问题的最佳解决方案可能是在下图中显示的黑色区域: enter image description here

水平显示从-90到+90度,垂直从-90到+90度显示(理想情况下应垂直为-80到+80度)。 我试着用:

public static void gluPartialDisk(GL10 gl, GLUquadric qobj, float innerRadius, float outerRadius, int slices, int loops, float startAngle, float sweepAngle)

但它不起作用。它显示黑屏。

总结问题是:

  1. 如何在图像上显示黑色区域时在球体上显示图像?
  2. 如何设置最小,最大水平和垂直旋转度(在user guide中是atvMin,atvMax,athMin,athMax选项,但我无法在panoramagl源代码中找到它)?< /强>

1 个答案:

答案 0 :(得分:0)

1)使用PLCylindricalPanorama设置正确的高度怎么样?

2)atvMin,atvMax,athMin,athMax在PLConstants中:

atv

public static final float kDefaultPitchMinRange = -90.0f;
public static final float kDefaultPitchMaxRange =  90.0f;

ath

public static final float kRotationMinValue =   -180.0f;
public static final float kRotationMaxValue =    180.0f;