The OBJ model of learning OpenGL under QT

Source: Internet
Author: User

My obj format here is not the intermediate file produced by C + + code, but that g what wave company obj format, the format is very simple, the function is to take to store some basic information of the 3D model. Used to be easy to read under the VS2005, this time for Qt, fortunately, QT company to the customer very attentively and responsible, in its qtlab found a good class and code. be used to successfully import obj~

Cut to the chase.
First this class will need to refer to the file point3d.h, which reads as follows:

#ifndef Point3d_h
#define Point3d_h

#include "math.h"

#include <qglobal.h>

struct POINT3D
{
float x, y, Z;

Point3D ()
: X (0)
, y (0)
, Z (0)
{
}

Point3D (float x_, float y_, float z_)
: X (X_)
, Y (Y_)
, Z (z_)
{
}

Point3D operator+ (const Point3D &p) const
{
Return Point3D (*this) + = p;
}

Point3D operator-(const Point3D &p) const
{
Return Point3D (*this)-= p;
}

Point3D operator* (float f) const
{
Return Point3D (*this) *= F;
}
Point3D &operator+= (const Point3D &p)
{
x + = p.x;
Y + = p.y;
z + = p.z;
return *this;
}

Point3D &operator-= (const Point3D &p)
{
X-= p.x;
Y-= p.y;
Z-= p.z;
return *this;
}

BOOL operator== (const Point3D &p)
{
if ((x==p.x) && (y==p.y) && (z==p.z))
return true;
return false;
}

Point3D &operator*= (float f)
{
x *= F;
Y *= F;
Z *= F;
return *this;
}

Point3D normalize () const
{
float R = 1. /sqrt (x * x + y * y + z * z);
return Point3D (x * r, y * r, Z * r);
}
Float &operator[] (unsigned int index) {
Q_assert (Index < 3);
return (&X) [index];
}

Const FLOAT &operator[] (unsigned int index) const {
Q_assert (Index < 3);
return (&X) [index];
}
};

inline float dot (const Point3D &a, const Point3D &b)
{
Return a.x * b.x + a.y * b.y + a.z * B.Z;
}

Inline Point3D Cross (const Point3D &a, const Point3D &b)
{
Return Point3D (A.Y * b.z–a.z * b.y,
A.Z * b.x–a.x * b.z,
a.x * B.Y–A.Y * b.x);
}

#endif

Then there is the content of Model.h:

#ifndef Model_h
#define Model_h

#include <QString>
#include <QVector>

#include <math.h>

#include "Point3d.h"

Class Model
{
Public
Model () {}
Model (const QString &filepath);

Draw a model
void Render (bool wireframe = FALSE, bool Normals = false) const;

QString FileName () const {return m_filename;}
int faces () const {return m_pointindices.size ()/3;}
int edges () const {return m_edgeindices.size ()/2;}
int points () const {return m_points.size ();}

Private
QString m_filename;//file name
qvector<point3d> m_points;//Vertex Information
qvector<point3d> m_normals;//Vector Information
Qvector<int> m_edgeindices;//Edge Index
qvector<int> m_pointindices;//Point Index
};

#endif

Finally, the content of Model.cpp:

#include "model.h"

#include <QFile>
#include <QTextStream>
#include <QVarLengthArray>

#include <QtOpenGL>

Model::model (const QString &filepath)
: M_filename (Qfileinfo (FilePath). FileName ())
{
QFile file (FilePath);
if (!file.open (qiodevice::readonly))
Return

Point3D boundsmin (1e9, 1e9, 1e9);
Point3D Boundsmax ( -1E9,-1E9,-1E9);

Qtextstream in (&file);
while (!in.atend ()) {
QString input = In.readline ();
if (Input.isempty () | | input[0] = = ' # ')
Continue

Qtextstream ts (&input);
QString ID;
TS >> ID;
if (id = = "V") {
Point3D p;
for (int i = 0; i < 3; ++i) {
TS >> P[i];
Boundsmin[i] = Qmin (Boundsmin[i], p[i]);
Boundsmax[i] = QMax (Boundsmax[i], p[i]);
}
M_points << p;
} else if (id = = "F" | | id = = "fo") {
Qvarlengtharray<int, 4> p;

while (!ts.atend ()) {
QString Vertex;
TS >> vertex;
const int vertexindex = Vertex.split ('/'). Value (0). ToInt ();
if (Vertexindex)
P.append (Vertexindex > 0 vertexindex–1:m_points.size () + Vertexindex);
}

for (int i = 0; i < p.size (); ++i) {
const int EDGEA = P[i];
const int EDGEB = p[(i + 1)% p.size ()];

if (Edgea < EDGEB)
M_edgeindices << Edgea << Edgeb;
}

for (int i = 0; i < 3; ++i)
M_pointindices << P[i];

if (p.size () = = 4)
for (int i = 0; i < 3; ++i)
M_pointindices << p[(i + 2)% 4];
}
}

Const Point3D bounds = boundsmax–boundsmin;
Const Qreal scale = 1/qmax (Bounds.x, QMax (Bounds.y, bounds.z));
for (int i = 0; i < m_points.size (); ++i)
M_points[i] = (m_points[i]– (boundsmin + bounds * 0.5)) * scale;

M_normals.resize (M_points.size ());
for (int i = 0; i < m_pointindices.size (); i + = 3) {
Const Point3D A = m_points.at (m_pointindices.at (i));
Const Point3D B = m_points.at (m_pointindices.at (i+1));
Const Point3D c = m_points.at (m_pointindices.at (i+2));

Const Point3D Normal = Cross (B–a, c–a). Normalize ();

for (int j = 0; j < 3; ++j)
m_normals[m_pointindices.at (i + j)] + = normal;
}

for (int i = 0; i < m_normals.size (); ++i)
M_normals[i] = M_normals[i].normalize ();
}

void Model::render (bool wireframe, bool normals) const
{
    glenable (gl_depth_test);
    glenableclientstate (Gl_vertex_array);
    if (wireframe) {
        glvertexpointer (3, gl_float, 0 , (float *) m_points.data ());
        gldrawelements (Gl_lines, M_edgeindices.size (), Gl_unsigned_int, m_ Edgeindices.data ());
   } else {
        glenable (gl_lighting);
        glenable (GL_LIGHT0);
        glenable (gl_color_material);
        Glshademodel (gl_smooth);

Glenableclientstate (Gl_normal_array);
Glvertexpointer (3, gl_float, 0, (FLOAT *) m_points.data ());
Glnormalpointer (gl_float, 0, (FLOAT *) m_normals.data ());
Gldrawelements (Gl_triangles, M_pointindices.size (), Gl_unsigned_int, M_pointindices.data ());

Gldisableclientstate (Gl_normal_array);
Gldisable (gl_color_material);
Gldisable (GL_LIGHT0);
Gldisable (gl_lighting);
}

if (normals) {
Qvector<point3d> normals;
for (int i = 0; i < m_normals.size (); ++i)
Normals << m_points.at (i) << (m_points.at (i) + m_normals.at (i) * 0.02f);
Glvertexpointer (3, gl_float, 0, (FLOAT *) normals.data ());
Gldrawarrays (gl_lines, 0, Normals.size ());
}
Gldisableclientstate (Gl_vertex_array);
Gldisable (gl_depth_test);
}

In the place where the external obj model needs to be called, declare an object of that class, enter the URI of the model in the constructor, and then call the Render function OK. Oh, the package is very thorough and powerful, I wish you success.

If there is anything wrong in the article, please point out that it is also convenient for those who see it later to take less detours.

If there is content in the article to help you, but also hope that can not be stingy time to leave words, as my motivation, hehe ~.

Beyond C + + original articles, reproduced please indicate the source and keep the original link

This article link: http://www.beyondc.cn/obj-model-under-the-load-qt.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.