手工绘制球形

  1. 生成uv坐标;
  2. 计算LLA坐标;
  3. 生成纹理坐标;
  4. 设置纹理;
#include <Windows.h>
#include <osg\Node>
#include <osg\Group>
#include <osg\Geometry>
#include <osg\MatrixTransform>
#include <osg/Point>
#include <osg/LineWidth>
#include <osg/LineStipple>
#include <osg/TexGen>
#include <osg/ShapeDrawable>

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgDB/ReadFile>

#include <osgGA/StateSetManipulator>
#include <osgGA/GUIEventHandler>
#include <osgGA/GUIEventAdapter>
#include <osgGA//GUIActionAdapter>

osg::Vec3 computeXYZ(float u, float v)
{
	float x = sin(osg::PI*v)*cos(2.0f*osg::PI*u);
	float y = sin(osg::PI*v)*sin(2.0f*osg::PI*u);
	float z = cos(osg::PI*v);
	return osg::Vec3(x, y, z);
}

osg::Geometry* createSphereGeometry(float r, int hint)
{
	osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();

	//设置顶点
	//手动压入纹理坐标
	osg::ref_ptr<osg::Vec3Array> vertex = new osg::Vec3Array();
	osg::ref_ptr<osg::Vec2Array> coord = new osg::Vec2Array();
	for (int i = 0; i <= hint; ++i)
	{
		for (int j = 0; j <= hint; ++j)
		{
			float u = (float)i / (float)hint;
			float v = (float)j / (float)hint;

			osg::Vec3 pos = computeXYZ(u, v);
			vertex->push_back(pos*r);
			coord->push_back(osg::Vec2(u, 1.0 - v));
		}
	}
	geometry->setVertexArray(vertex);
	geometry->setTexCoordArray(0, coord);

	//设置颜色
	osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array();
	colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
	geometry->setColorArray(colors, osg::Array::BIND_OVERALL);

	//图元装配
	for (int i = 0; i < hint; ++i)
	{
		osg::ref_ptr<osg::DrawElementsUInt> draw_elements = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP);
		for (int j = 0; j <= hint; ++j)
		{
			draw_elements->addElement(i * (hint + 1) + j);
			draw_elements->addElement((i + 1) * (hint + 1) + j);
		}
		geometry->addPrimitiveSet(draw_elements);
	}

	return geometry.release();
}

int main()
{
	osgViewer::Viewer viewer;

	osg::ref_ptr<osg::Group> group = new osg::Group();
	viewer.setSceneData(group);

	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
	geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
	geode->getOrCreateStateSet()->setAttributeAndModes(new osg::PolygonMode(osg::PolygonMode::FRONT, osg::PolygonMode::FILL));
	osg::ref_ptr<osg::Geometry> geometry = createSphereGeometry(1.0, 36);
	geode->addDrawable(geometry);

	osg::ref_ptr<osg::Image> image = osgDB::readImageFile("Images\\land_shallow_topo_2048.jpg");
	osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D();
	texture->setImage(image);
	texture->setDataVariance(osg::Object::DYNAMIC);
	texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
	texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
	texture->setWrap(osg::Texture::WRAP_R, osg::Texture::REPEAT);
	texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
	texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture);

	group->addChild(geode);

	viewer.setUpViewInWindow(100, 100, 500, 400);
	return viewer.run();
}

posted @ 2021-09-02 21:39  暹罗吹雪  阅读(81)  评论(0编辑  收藏  举报