Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[QT5, OpenGL] Wczytywanie Modelu OBJ wraz z texturą - problem

Ostatnio zmodyfikowano 2017-04-29 14:32
Autor Wiadomość
wojownik266
Temat założony przez niniejszego użytkownika
[QT5, OpenGL] Wczytywanie Modelu OBJ wraz z texturą - problem
» 2017-04-24 18:24:26
Chciałbym się nauczyć wczytywać  modele obj wraz z teksturą do programu i przeszukując zasoby Google pod tym kontem trafiłem na tą oto stronę:
http://stackoverflow.com/questions/30422962/qtopengl-load-obj-format-with-qimage-texture
Kod podany na tej stronie zaimplementowałem w Qt  i moje dokonania przedstawiam poniżej. Trochę tym kodem się pobawiłem ale ta zabawa do niczego dobrego mnie nie doprowadziła…  Na końcu tej strony (link powyżej) jest podane rozwiązanie problemu ale nie wiem jak z tym rozwiązaniem dojść do ładu. Dlatego o ile nie stanowiłoby  to jakiegoś większego problemu to może wspólnymi siłami doprowadzilibyśmy ten program do stanu używalności? Przydał by się nie tylko mnie… Więc?
Oto kod z dodaną przeze mnie klasą „QGLBegin.h”:

C/C++
#-------------------------------------------------
#
# Project created by QtCreator 2017-04-24T16:30:10
#
#-------------------------------------------------

QT += core gui opengl

greaterThan( QT_MAJOR_VERSION, 4 )
    : QT += widgets TARGET = Obj_Loader_001 TEMPLATE = app SOURCES += main.cpp\
 mainwindow.cpp cpp\
 qglbegin.cpp cpp\
 model.cpp HEADERS += mainwindow.h h\
 qglbegin.h h\
 model.h FORMS += mainwindow.ui LIBS += - lopengl32 - lglu32
C/C++
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
    class MainWindow;
}

class MainWindow
    : public QMainWindow
{
    Q_OBJECT
   
public:
    explicit MainWindow( QWidget * parent = 0 );
    ~MainWindow();
   
private slots:
    void on_pushButton_pressed();
   
private:
    Ui::MainWindow * ui;
};

#endif // MAINWINDOW_H
C/C++
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "qglbegin.h"

MainWindow::MainWindow( QWidget * parent )
    : QMainWindow( parent )
     , ui( new Ui::MainWindow )
{
    ui->setupUi( this );
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_pressed()
{
    ui->openGLWidget->Rysuj();
}
Model.h
C/C++
#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
C/C++
#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 );
}
Qglbegin.h
C/C++
#ifndef QGLBEGIN_H
#define QGLBEGIN_H

#include <QtWidgets>
#include <QTimer>

#include<GL/gl.h>
#include<Gl/glu.h>

#include "model.h"

class QGLBegin
    : public QOpenGLWidget
{
    Q_OBJECT
public:
    explicit QGLBegin( QWidget * parent = 0 );
    void Rysuj();
   
   
   
protected:
    void initializeGL();
    void paintGL();
    void resizeGL( int width, int height );
   
    signals:
   
public slots:
   
private:
public:
    Model * OBJ;
   
   
};

#endif // QOGLBEGIN_H
Qglbegin.cpp
C/C++
#include "qglbegin.h"
#include <QOpenGLWidget>

#include <gl\gl.h>
#include <gl\glu.h>

#include "model.h"

QGLBegin::QGLBegin( QWidget * parent )
    : QOpenGLWidget( parent )
{
   
}
void QGLBegin::initializeGL()
{
    glEnable( GL_DEPTH_TEST );
   
}

void QGLBegin::paintGL()
{
   
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
   
    glLoadIdentity();
    gluLookAt( 0.0f, 0.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f );
   
    Model mod;
    mod.render();
}

void QGLBegin::resizeGL( int width, int height )
{
    glViewport( 0, 0, width, height );
   
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
   
    gluPerspective( 60.0f,( float ) width /( float ) height, 1.0f, 1000.0f );
   
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
   
   
}


void QGLBegin::Rysuj()
{
    update();
}
P-160469
wojownik266
Temat założony przez niniejszego użytkownika
» 2017-04-25 02:42:10
Coś mi się zdaje że z tego przywracania do „jako takiej używalności”  nic nie wyjdzie bo ten program ogólnie jest źle zrobiony…  Tak że z czystym sumieniem administrator może przenieść ten wątek do kosza:((
P-160481
VND
» 2017-04-25 19:55:53
Co do "jako takiej używalności".
Masz wskaźnik na model w klasie QGLBegin, ale nic nie wczytujesz, więc nic się nie wyświetla.
W metodzie initializeGL wczytaj model
OBJ = new Model( "ścieżka do modelu obj" );

a w paintGL go wyświetl
OBJ->render();


P-160492
wojownik266
Temat założony przez niniejszego użytkownika
» 2017-04-26 21:24:20
Zrobiłem tak jak mówisz i dostałem taki komunikat:
"This application has requested Runtime to terminate it on unsual way..."
P-160535
VND
» 2017-04-27 01:16:42
Obstawiam nieprawidłowy plik obj.
Użyj tych plików.
Przy okazji jest tam opis ich budowy.
P-160540
wojownik266
Temat założony przez niniejszego użytkownika
» 2017-04-27 12:52:59
Gdybyś obstawił jakieś wyścigi konne albo jakiś zakład byłbyś dzisiaj bardzo bogatym człowiekiem a tak będziesz musiał zadowolić się jedynie  moimi nieśmiałymi  podziękowaniami. Dziękuję:) Plik co prawda bez tekstury ale bardzo ładnie się wyświetla... Ten poprzedni zrobiłem w blenderze tak na szybko i musiałem coś poknocić z ustawieniami. Ale teraz jak już wiem że program działa będę miał zajęcie na jakiś czas... Jeszcze raz dzięki i miłego dnia!
P-160547
wojownik266
Temat założony przez niniejszego użytkownika
» 2017-04-27 15:54:03
A tak całkiem przy okazji to dlaczego ten program nie chce wczytywać plików obj z blendera? Albo co zrobić aby je wczytywał?
P-160556
VND
» 2017-04-28 23:58:37
No to znów będę strzelał.
Nie zaznaczyłeś "Triangulate Faces" przy exporcie do obj, a tego wymaga Twój loader.
P-160590
« 1 » 2
  Strona 1 z 2 Następna strona