我怎么能用osg api在osgearth上绘制一个三角形

时间:2017-02-23 10:59:41

标签: c++ opengl osgearth

我想在地球上画三角形。 如果我按类osgEarth :: Features :: Feature绘制三角形则没有问题。

例如:

void DrawGeometryByFeature(ListVec3d& vecList, std::vector<unsigned int>& lstIndices)
{
        osgEarth::Symbology::Style shapeStyle;

        shapeStyle.getOrCreate<osgEarth::Symbology::PolygonSymbol>()->fill()->color() = osgEarth::Symbology::Color::Green;

        _polyFeature = new osgEarth::Features::Feature(new osgEarth::Symbology::MultiGeometry, s_mapNode->getMapSRS(), shapeStyle);
        _polyNode = new osgEarth::Annotation::FeatureNode(s_mapNode, _polyFeature);
        osgEarth::Symbology::MultiGeometry* pGeometry = (MultiGeometry*)_polyNode->getFeature()->getGeometry();

        pGeometry->clear();
        _polyNode->setStyle(shapeStyle);
        int index = 0;
        for (std::vector<unsigned int>::iterator iit = lstIndices.begin();
                iit != lstIndices.end(); iit++) {
                index++;
                if ((index + 1) % 3 == 0) {
                        osgEarth::Symbology::Geometry* polygen = new osgEarth::Symbology::Geometry();
                        polygen->push_back(vecList[lstIndices[index - 2]]);
                        polygen->push_back(vecList[lstIndices[index - 1]]);
                        polygen->push_back(vecList[lstIndices[index]]);
                        pGeometry->add(polygen);
                }
        }
        _polyNode->init();

        BBoxNodes.push_back(_polyNode);
        s_mapNode->addChild(_polyNode);
}

但我希望更有效地绘制它,所以我尝试通过osg API绘制它

例如:

void DrawGeometryByOsg(std::vector<osg::Vec3d> vecList, std::vector<unsigned int>& lstIndices, int color, long type)
{
        // create Geometry object to store all the vertices and lines primitive.
        osg::Geometry* polyGeom = new osg::Geometry();

        // note, first coord at top, second at bottom, reverse to that buggy OpenGL image..
        const size_t numCoords  = lstIndices.size();
        osg::Vec3* myCoords = new osg::Vec3[numCoords];
        unsigned int index = 0;

        osg::Vec3Array* normals = new osg::Vec3Array(/*numCoords/3*/);
        for (std::vector<unsigned int>::iterator it = lstIndices.begin(); it != lstIndices.end(); it++){
                myCoords[index++] = vecList[*it];
                if(index%3 == 2){
                        //
                        osg::Vec3d kEdge1 = myCoords[index-1] - myCoords[index-2];
                        osg::Vec3d kEdge2 = myCoords[index] - myCoords[index - 2];
                        osg::Vec3d normal = kEdge1^kEdge2;
                        //normal.normalize();
                        normals->push_back(normal);
                        //
                }
        }
        osg::Vec3Array* vertices = new osg::Vec3Array(numCoords, myCoords);
        polyGeom->setVertexArray(vertices);

        osg::Vec4Array* colors = new osg::Vec4Array;

        colors->push_back(osg::Vec4(0.0f, 0.8f, 0.0f, 1.0f));


        polyGeom->setColorArray(colors, osg::Array::BIND_OVERALL);
        polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, numCoords));

        osg::Geode* geode = new osg::Geode();

        geode->addDrawable(polyGeom);

        s_mapNode->addChild(geode);
}

但我用Osg API绘制的宝石总是在摇晃....(¯﹏¯;)

你可以告诉我代码中的错误在哪里?

1 个答案:

答案 0 :(得分:0)

任何时候你有&#34;摇晃&#34;您可能遇到浮点精度问题的几何。 OpenGL处理​​32位浮点坐标。因此,如果您的几何体使用较大的坐标值(就像在osgEarth这样的地心中的地图中),那么当这些值被发送到GPU时会被裁剪,并且当相机移动时会发生抖动/抖动。

要解决此问题,请相对于本地来源表达您的数据。在某处选择一个双精度点 - 几何体的质心通常是一个好地方 - 并使其成为您的本地原点。然后翻译所有双精度坐标,使它们相对于该原点。最后,使用MatrixTransform将几何体作为父级,将MatrixFnsform转换为实际的双精度位置。

希望这有帮助!