Apa*_*che 12 c++ opengl openscenegraph
我花了很长时间才使这个工作,但我的Sphere不会显示.
使用以下代码来实现我的功能:
使用Visual C++在Opengl中创建3D球体
其余的是OSG和osg :: Geometry.
(注意:不是ShapeDrawable,因为您无法使用它实现自定义形状.)
将顶点,法线,texcoords添加到VecArrays中.
首先,我怀疑行为不端,因为我保存的物品是半空的.
有没有办法将现有描述转换为OSG?
原因?我想了解如何在以后创建对象.
事实上,它与后来的任务有关,但目前我只是预先准备.
旁注:因为我必须没有索引,所以我把它们排除了.
但是没有它们,我的圆筒显示得很好.
警告:我不是OSG专家.但是,我确实做了一些研究.
OSG要求以逆时针顺序定义所有面,以便背面剔除可以拒绝"面向"的面.您用于生成球体的代码不会以逆时针顺序生成所有面.
你可以通过几种方式解决这个问题:
上面的选项1会将您的多边形总数限制为所需的数量.选项2将为您提供从球体外部以及内部可见的球体.
要实现选项2,您只需要从链接到的代码修改此循环:
indices.resize(rings * sectors * 4);
std::vector<GLushort>::iterator i = indices.begin();
for(r = 0; r < rings-1; r++)
for(s = 0; s < sectors-1; s++) {
*i++ = r * sectors + s;
*i++ = r * sectors + (s+1);
*i++ = (r+1) * sectors + (s+1);
*i++ = (r+1) * sectors + s;
}
Run Code Online (Sandbox Code Playgroud)
将四元组加倍,如下所示:
indices.resize(rings * sectors * 8);
std::vector<GLushort>::iterator i = indices.begin();
for(r = 0; r < rings-1; r++)
for(s = 0; s < sectors-1; s++) {
*i++ = r * sectors + s;
*i++ = r * sectors + (s+1);
*i++ = (r+1) * sectors + (s+1);
*i++ = (r+1) * sectors + s;
*i++ = (r+1) * sectors + s;
*i++ = (r+1) * sectors + (s+1);
*i++ = r * sectors + (s+1);
*i++ = r * sectors + s;
}
Run Code Online (Sandbox Code Playgroud)
不过,这确实是"更大的锤子"解决方案.
就个人而言,我很难弄清楚为什么原始循环不够; 通过几何学直观地感知它,它感觉它已经产生了CCW面,因为每个连续的环都在前面,并且每个连续的扇区在前面的球体表面周围是CCW.因此,原始顺序本身应该是最接近观察者的面部的CCW.
编辑 使用您之前链接的OpenGL代码和今天链接的OSG教程,我将我认为正确的程序放在一起,以生成osg::Geometry
/ osg::Geode
为球体.我无法测试以下代码,但是检查它,看起来是正确的,或者至少在很大程度上是正确的.
#include <vector>
class SolidSphere
{
protected:
osg::Geode sphereGeode;
osg::Geometry sphereGeometry;
osg::Vec3Array sphereVertices;
osg::Vec3Array sphereNormals;
osg::Vec2Array sphereTexCoords;
std::vector<osg::DrawElementsUInt> spherePrimitiveSets;
public:
SolidSphere(float radius, unsigned int rings, unsigned int sectors)
{
float const R = 1./(float)(rings-1);
float const S = 1./(float)(sectors-1);
int r, s;
sphereGeode.addDrawable( &sphereGeometry );
// Establish texture coordinates, vertex list, and normals
for(r = 0; r < rings; r++)
for(s = 0; s < sectors; s++)
{
float const y = sin( -M_PI_2 + M_PI * r * R );
float const x = cos(2*M_PI * s * S) * sin( M_PI * r * R );
float const z = sin(2*M_PI * s * S) * sin( M_PI * r * R );
sphereTexCoords.push_back( osg::Vec2(s*R, r*R) );
sphereVertices.push_back ( osg::Vec3(x * radius,
y * radius,
z * radius) );
sphereNormals.push_back ( osg::Vec3(x, y, z) );
}
sphereGeometry.setVertexArray ( &spehreVertices );
sphereGeometry.setTexCoordArray( &sphereTexCoords );
// Generate quads for each face.
for(r = 0; r < rings-1; r++)
for(s = 0; s < sectors-1; s++)
{
spherePrimitiveSets.push_back(
DrawElementUint( osg::PrimitiveSet::QUADS, 0 )
);
osg::DrawElementsUInt& face = spherePrimitiveSets.back();
// Corners of quads should be in CCW order.
face.push_back( (r + 0) * sectors + (s + 0) );
face.push_back( (r + 0) * sectors + (s + 1) );
face.push_back( (r + 1) * sectors + (s + 1) );
face.push_back( (r + 1) * sectors + (s + 0) );
sphereGeometry.addPrimitveSet( &face );
}
}
osg::Geode *getGeode() const { return &sphereGeode; }
osg::Geometry *getGeometry() const { return &sphereGeometry; }
osg::Vec3Array *getVertices() const { return &sphereVertices; }
osg::Vec3Array *getNormals() const { return &sphereNormals; }
osg::Vec2Array *getTexCoords() const { return &sphereTexCoords; }
};
Run Code Online (Sandbox Code Playgroud)
您可以使用这些getXXX
方法获取各种部分.我没有看到如何将表面法线挂钩到任何东西,但我将它们存储在Vec2Array中.如果您对它们有用,那么它们就会被计算和存储,并等待被钩住.