Opengl 裁剪球体

Opengl 裁剪球体,opengl,3d,Opengl,3d,他在这里提出了一个问题: 可能是因为它更深入地理信息系统,所以我们转向了OpenGL中更基本、更具体的实现,以获得所需的输出 我只是简单地重写/复制了一些函数,这些函数正在绘制半球体,并将GL零件更改为基本插入剪裁。我能够画出以某个位置(纬度、经度)为中心的半球,半径可能是2000。但当我用飞机切割它时,什么都没发生。请检查平面的方程式(其平行于地球表面的平面高度可能为1000,因此(0,0,+11000)) 基类具有drawUnitSphere,因此可能会导致一些问题,因此尝试使用GL的gl

他在这里提出了一个问题:

可能是因为它更深入地理信息系统,所以我们转向了OpenGL中更基本、更具体的实现,以获得所需的输出

我只是简单地重写/复制了一些函数,这些函数正在绘制半球体,并将GL零件更改为基本插入剪裁。我能够画出以某个位置(纬度、经度)为中心的半球,半径可能是2000。但当我用飞机切割它时,什么都没发生。请检查平面的方程式(其平行于地球表面的平面高度可能为1000,因此(0,0,+11000))

基类具有drawUnitSphere,因此可能会导致一些问题,因此尝试使用GL的gluSphere()。但甚至看不到地球上的球体。使用“平移”将其移动到我的位置(纬度/经度),但仍然无法看到它。可能是lat/lon和笛卡尔坐标的一些问题,或者是剪辑代码的放置。请查收

代码如下:

@Override
public void drawSphere(DrawContext dc)
{
    double[] altitudes = this.getAltitudes(dc.getVerticalExaggeration());
    boolean[] terrainConformant = this.isTerrainConforming();
    int subdivisions = this.getSubdivisions();

    if (this.isEnableLevelOfDetail())
    {
        DetailLevel level = this.computeDetailLevel(dc);

        Object o = level.getValue(SUBDIVISIONS);
        if (o != null && o instanceof Integer)
            subdivisions = (Integer) o;            
    }

    Vec4 centerPoint = this.computePointFromPosition(dc,
        this.location.getLatitude(), this.location.getLongitude(), altitudes[0], terrainConformant[0]);

    Matrix modelview = dc.getView().getModelviewMatrix();
    modelview = modelview.multiply(Matrix.fromTranslation(centerPoint));
    modelview = modelview.multiply(Matrix.fromScale(this.getRadius()));
    double[] matrixArray = new double[16];
    modelview.toArray(matrixArray, 0, false);

    this.setExpiryTime(-1L); // Sphere geometry never expires.

    GL gl = dc.getGL(); // GL initialization checks for GL2 compatibility.
    gl.glPushAttrib(GL.GL_POLYGON_BIT | GL.GL_TRANSFORM_BIT);
    try
    {

        gl.glEnable(GL.GL_CULL_FACE);
        gl.glFrontFace(GL.GL_CCW);

        // Were applying a scale transform on the modelview matrix, so the normal vectors must be re-normalized
        // before lighting is computed. In this case we're scaling by a constant factor, so GL_RESCALE_NORMAL
        // is sufficient and potentially less expensive than GL_NORMALIZE (or computing unique normal vectors
        // for each value of radius). GL_RESCALE_NORMAL was introduced in OpenGL version 1.2.
        gl.glEnable(GL.GL_RESCALE_NORMAL);

        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glPushMatrix();

        //clipping
        DoubleBuffer eqn1 = BufferUtils.createDoubleBuffer(8).put(new double[] {0, 0, 1, 100});
        eqn1.flip();
        gl.glClipPlane(GL.GL_CLIP_PLANE0, eqn1);
        gl.glEnable(GL.GL_CLIP_PLANE0);
        try
        {
            gl.glLoadMatrixd(matrixArray, 0);
            //this.drawUnitSphere(dc, subdivisions);
            gl.glLoadIdentity();
            gl.glTranslatef(75.2f, 32.5f, 0.0f);
            gl.glColor3f(1.0f, 0.0f, 0.0f);
            GLU glu = dc.getGLU();
            GLUquadric qd=glu.gluNewQuadric();
            glu.gluSphere(qd,3.0f,20,20);
        }
        finally
        {
            gl.glPopMatrix();
        }
    }
    finally
    {
        gl.glPopAttrib();
    }
}

@Override
public void drawUnitSphere(DrawContext dc, int subdivisions)
{
    Object cacheKey = new Geometry.CacheKey(this.getClass(), "Sphere", subdivisions);
    Geometry geom = (Geometry) this.getGeometryCache().getObject(cacheKey);
    if (geom == null || this.isExpired(dc, geom))
    {
        if (geom == null)
            geom = new Geometry();
        this.makeSphere(1.0, subdivisions, geom);
        this.updateExpiryCriteria(dc, geom);
        this.getGeometryCache().add(cacheKey, geom);
    }

    this.getRenderer().drawGeometry(dc, geom);
}

@Override
public void makeSphere(double radius, int subdivisions, Geometry dest)
{
    GeometryBuilder gb = this.getGeometryBuilder();
    gb.setOrientation(GeometryBuilder.OUTSIDE);

    GeometryBuilder.IndexedTriangleArray ita = gb.tessellateSphere((float) radius, subdivisions);
    float[] normalArray = new float[3 * ita.getVertexCount()];
    gb.makeIndexedTriangleArrayNormals(ita, normalArray);

    dest.setElementData(GL.GL_TRIANGLES, ita.getIndexCount(), ita.getIndices());
    dest.setVertexData(ita.getVertexCount(), ita.getVertices());
    dest.setNormalData(ita.getVertexCount(), normalArray);
}

我没有完全理解你的坐标和变换。但需要记住的一点是,当使用
glClipPlane()
指定剪辑平面时,剪辑平面将使用当前modelview矩阵的逆矩阵进行变换。因此,在进行该调用时,您需要查看当前的modelview矩阵。@Reto Koradi:谢谢,没有收到通知,因此无法响应。我仍然卡在剪辑部分。我可以看到球体,但剪裁没有发生。您提到“剪辑平面使用当前modelview矩阵的倒数进行变换”这是什么意思?我已经取得了一些进展,并在这里问了一个问题:,您可以检查我的最新代码并在那里作出答复