【问题标题】:QtOpenGL Load obj format with QImage textureQtOpenGL 使用 QImage 纹理加载 obj 格式
【发布时间】:2015-05-24 11:25:12
【问题描述】:

OBJ 加载正常,但纹理加载失败。我哪里做错了?

在 Model.h 中

#ifndef MODEL_H
#define MODEL_H

#include <QVector>
#include <QTextStream>
#include <QVector3D>
#include <QVector2D>
#include <QtOpenGL>

/* one texture only */

struct Face{
    QVector<QVector3D> v;
    QVector<QVector3D> vn;
    QVector<QVector2D> t;
    Face(){
        v.resize(3);
        vn.resize(3);
        t.resize(3);
    }
};

class Model
{
public:
    Model() {}
    Model(QString filename);
    void render();

    int faces() const { return Faces.size(); }
    int points() const { return Vertices.size(); }

private:
    QString fileName;
    QString textureName;
    QVector<QVector3D> Vertices; //v
    QVector<QVector3D> VNormals; //vn
    QVector<QVector2D> UVs;      //vt
    QVector<Face>      Faces;    //f
    GLuint texture;
    QImage textureImg;
    void LoadMTL(QString fn, QString MTLname);
    void LoadTexture();
};

#endif

在 Model.cpp 中

#include "Model.h"

Model::Model(QString filename)
{
    fileName = filename;
    QString textruename;
    QVector3D temp3D;
    QVector2D temp2D;
    if(!fileName.isEmpty())
    {
        QFile file(fileName);
        if (file.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            QTextStream fileText(&file);
            while (!fileText.atEnd())
            {
                QString fileLine = fileText.readLine();
                if(fileLine.startsWith("vn "))
                {
                    QStringList lineList = fileLine.split(" ");
                    temp3D.setX( lineList[1].toFloat() );
                    temp3D.setY( lineList[2].toFloat() );
                    temp3D.setZ( lineList[3].toFloat() );
                    VNormals.push_back(temp3D);
                }
                else if(fileLine.startsWith("vt "))
                {
                    QStringList lineList = fileLine.split(" ");
                    temp2D.setX( lineList[1].toFloat() );
                    temp2D.setY( lineList[2].toFloat() );
                    UVs.push_back(temp2D);
                }
                else if(fileLine.startsWith("v "))
                {
                    QStringList lineList = fileLine.split(" ");
                    temp3D.setX( lineList[1].toFloat() );
                    temp3D.setY( lineList[2].toFloat() );
                    temp3D.setZ( lineList[3].toFloat() );
                    Vertices.push_back(temp3D);
                }
                else if(fileLine.startsWith("f "))
                {
                    Face F;
                    QStringList lineList = fileLine.split(" ");

                    for(int i = 1; i <= 3; i++)
                    {
                        QStringList arg = lineList[i].split("/");
                        F.v[i-1] = Vertices[arg[0].toInt()-1];
                        F.t[i-1] = UVs[arg[1].toInt()-1];
                        F.vn[i-1] = VNormals[arg[2].toInt()-1];
                    }
                    Faces.push_back(F);
                }
                else if(fileLine.startsWith("mtllib "))
                {
                    QStringList lineList = fileLine.split(" ");
                    textruename = lineList[1];
                }
            }
        }
        file.close();
        QFileInfo fi(fileName);
        QString BaseName = fi.fileName();
        QString fn(fileName);
        fn.remove(fn.size() - BaseName.size(), BaseName.size());
        LoadMTL(fn, fn + textruename);
    }
}

void Model::render()
{
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable( GL_TEXTURE_2D );
    glBindTexture(GL_TEXTURE_2D, texture);
    glPushMatrix();
        glBegin(GL_TRIANGLES);
        for(int i = 0; i < Faces.size(); i++)
        {
            for(int j = 0; j < 3; j++)
            {
                glNormal3f(Faces[i].vn[j].x(), Faces[i].vn[j].y(), Faces[i].vn[j].z());
                glTexCoord2f(Faces[i].t[j].x(), Faces[i].t[j].y());
                glVertex3f(Faces[i].v[j].x(), Faces[i].v[j].y(), Faces[i].v[j].z());
            }
        }
        glEnd();
    glPopMatrix();
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);
    glDisable(GL_LIGHT0);
}

void Model::LoadMTL(QString fn, QString MTLname)
{
    if(!MTLname.isEmpty())
    {
        QFile file(MTLname);
        if (file.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            QTextStream fileText(&file);
            while (!fileText.atEnd())
            {
                QString fileLine = fileText.readLine();
                if(fileLine.startsWith("map_Kd "))
                {
                    QStringList lineList = fileLine.split(" ");
                    textureName = fn + lineList[1];
                    LoadTexture();
                }
            }
        }
        file.close();
    }
}

void Model::LoadTexture()
{
    textureImg = QImage(textureName);

    textureImg = QGLWidget::convertToGLFormat( textureImg );
    glGenTextures( 1, &texture );
    glBindTexture( GL_TEXTURE_2D, texture );

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureImg.width(), textureImg.height(), 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, textureImg.bits());
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glBindTexture( GL_TEXTURE_2D, 0 );
}

当我这样做时

OBJ = new Model("C:/Users/username/Desktop/OBJ.obj");
OBJ->render();

似乎 Model::LoadTexture() 不起作用。

我看过这个帖子,但是没有加载纹理。

Textures openGl. C++, qt

请不要推荐任何可以加载 3D 格式的库。

【问题讨论】:

  • 纹理加载代码是否在目标 OpenGL 上下文处于活动状态时调用?
  • 我不知道你的意思是什么,有什么例子吗?谢谢。
  • 在您可以使用 OpenGL 之前,您需要创建一个有效的 OpenGL 上下文并使其处于活动状态。在 QGLWidget 的情况下,只有在 …GL 方法(initializeGL、paintGL)或调用 makeCurrent 之后(必须通过调用 doneCurrent 来应对)才会出现这种情况。
  • this 是我正在做的事情。如您所见,猴子身上没有纹理。我认为已经创建了有效的 OpenGL 上下文。
  • 请将您的答案作为答案发布,并回滚您对问题的编辑。我们喜欢在此处将 Qs 和 As 分开(并且根本不喜欢在标题中使用标记)。

标签: c++ qt opengl


【解决方案1】:

问题已解决:

白色

OBJ = new Model("C:/Users/username/Desktop/OBJ.obj");

进入initializeGL()而不是构造函数。

感谢 datenwolf !!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 2016-07-19
    • 2014-07-11
    • 1970-01-01
    相关资源
    最近更新 更多