QtOpenGL 使用 QImage 纹理加载 obj 格式 [英] QtOpenGL Load obj format with QImage texture
本文介绍了QtOpenGL 使用 QImage 纹理加载 obj 格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
OBJ 加载正常,但纹理加载失败.我哪里做错了?
OBJ loading is OK, but texture loading fails. where did I do wrong?
在 Model.h 中
in 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 中
in 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() 不起作用.
It seems Model::LoadTexture() doesn't work.
我看过这个帖子,但没有加载纹理.
I have seen this POST, but texture was not loaded.
请不要推荐任何可以加载 3D 格式的库.
Please don't recommend any library which can load 3D format.
推荐答案
问题已解决:
白色
OBJ = new Model("C:/Users/username/Desktop/OBJ.obj");
进入 initializeGL() 而不是构造函数.
into initializeGL() instead of constructor.
感谢 datenwolf !!
Thanks to datenwolf !!
这篇关于QtOpenGL 使用 QImage 纹理加载 obj 格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文