在一个顶点和索引缓冲区中加载包含多个对象的.obj文件

时间:2017-12-01 09:33:39

标签: c++ qt opengl

我有.obj加载方法,它读取所有几何信息并一次性将它附加到顶点和索引缓冲区。

然而,我的3D模型比简单的立方体更复杂,并且包含了我需要以某种方式进行交互的几个对象。使用对象名称标签读取行不是问题,但我不明白如何使用 QGLBuffers 正确组织此过程。我可以将不同的对象数据存储在一个缓冲区中

添加循环是否更好直接在load方法中创建新对象,或者在每次到达新的'o'标记时以某种方式重新加载 initializeGL()中的方法?

我应该创建一个新类,它将继承默认对象类,使用load方法存储不同的对象,或者可以将所有内容存储在一个类中。(我已经阅读了几篇有关继承的文章和示例,但没有太多实践有它并且不太明白在这种情况下我该怎么办?)

我试图找到在 OpenGL 中加载多个对象的示例,查看 Assimp库的代码,但我没有找到任何与对象名称相关的内容,既不将对象数据存储在单个顶点和索引缓冲区中。

我的SceneObject类

class SceneObject
{
public:
SceneObject();
typedef struct {
    QVector3D vertex;
    QVector3D normal;
    QVector2D texcoord;
} Point;

typedef unsigned int PointIdxType;
const GLuint GLPointIdxType = GL_UNSIGNED_INT;

typedef unsigned int FaceIdxType;

QVector<QVector3D> vertices;
QVector<QVector3D> face_normal;
QVector<QVector2D> texcoords;
QVector<Point> points;
QHash<QString,PointIdxType> string_to_point_index;
QVector<PointIdxType> faces_points_indices;
QVector<QVector<FaceIdxType> > point_faces;

QList<SceneObject *> objects;

QGLBuffer vertex_buffer;
QGLBuffer *index_buffer;

void loadObjModel(QString path);
};

initializeGL()

中使用SceneObject
curObj = new SceneObject;

if (curObj->vertex_buffer.create())
{
    curObj->vertex_buffer.bind();
    curObj->vertex_buffer.setUsagePattern(QGLBuffer::StaticDraw);
    curObj->vertex_buffer.release();
}
else qDebug() << "Couldn't create vertex_buffer";

curObj->index_buffer = new QGLBuffer(QGLBuffer::IndexBuffer);
if (curObj->index_buffer&&(curObj->index_buffer->create()))
{
    curObj->index_buffer->bind();
    curObj->index_buffer->setUsagePattern(QGLBuffer::StaticDraw);
    curObj->index_buffer->release();
}
else qDebug() << "Couldn't create index_buffer";

curObj->loadObjModel("model.obj");

painGL()

中使用SceneObject
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

curObj->vertex_buffer.bind();
curObj->index_buffer->bind();
glVertexPointer(3,GL_FLOAT,sizeof(SceneObject::Point),0);
glNormalPointer(GL_FLOAT,sizeof(SceneObject::Point),(void*)12);
glTexCoordPointer(2,GL_FLOAT,sizeof(SceneObject::Point),(void*)24);

glDrawElements(GL_TRIANGLES,curObj->faces_points_indices.count(),curObj->GLPointIdxType,0);
curObj->index_buffer->release();
curObj->vertex_buffer.release();

glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

loadObjModel 代码

vertices.clear();
texcoords.clear();
string_to_point_index.clear();
points.clear();
point_faces.clear();
face_normal.clear();
faces_points_indices.clear();

***
reading obj file and appending data
***

vertex_buffer.bind();
vertex_buffer.allocate(points.constData(),points.count()*sizeof(Point));
vertex_buffer.release();

index_buffer->bind();
index_buffer->allocate(faces_points_indices.constData(),faces_points_indices.count()*sizeof(PointIdxType));
index_buffer->release();

obj_file.close();

0 个答案:

没有答案