2

QGLWidgetサブクラスを使用してQtのNeHeOGLチュートリアルに従っています。これまでのところ問題はありませんでした。6番目のチュートリアルでは回転ボックスのテクスチャリングを紹介するテクスチャマッピングについて。私はすべてが機能しているので、キューブの両側に独自のテクスチャを追加するためにいじり回してみました。QGLWidget :: bindTexture()関数を使用して、Qtリソースシステムを介して保存された256x256 bmpファイルをロードし、GLuintIDをプライベートメンバー配列に保存しました。paintGL()では、正方形の各面に対してglBegin(GL_QUADS)とglEnd()を呼び出す前に、引数としてGL_TEXTURE_2DとGLuint配列要素の1つを使用してglBindTexture()を呼び出します。コンパイルは正常ですが、ボックスが完全に白くレンダリングされるか(テクスチャが見つからないかのように)、回転描画中に画面全体にランダムな線が表示されて、黒と白のアーティファクトが発生します。

いじりながら、クラス宣言の最後に別のプライベートデータメンバーを追加することで問題を解決しました。魔法のように機能し始め、GLuintテクスチャ配列の宣言をクラス宣言の上位に移動することにしました。 。私はメモリアライメントについてかなり無知です、そしてそれは起こっていることの最も明白な原因のように思われます、そして私はここで起こっていることの説明が欲しいです。

重要な場合、これはQt 4.6にあり、MinGW5.1.6のGCC4.4.0およびGNUMake 3.8.1でコンパイルされています(アップグレードする必要があります)。

コード:glwidget.hpp、問題のある宣言は下部にコメントされています

    #ifndef GLWIDGET_HPP
    #define GLWIDGET_HPP

    #include <QtOpenGL>

    class QTimer;

    class GLWidget : public QGLWidget
    {
    Q_OBJECT

    public:
        GLWidget( QWidget *parent = 0 );
        ~GLWidget();

    protected:
        void initializeGL();
        void paintGL();
        void resizeGL( int width, int height );

    private:
        void drawCube();
        void loadTextures();

        QTimer  *m_timer;
        GLuint  m_textures[6]; // doesn't cause rendering problems here
        GLfloat m_xrot, m_yrot, m_zrot;
    //  GLuint  m_textures[6]; // causes rendering problems if declared here
    };

    #endif

glwidget.cpp

    #include "glwidget.hpp"

    #include <QTimer>

    GLWidget::GLWidget( QWidget *parent )
        : QGLWidget( QGLFormat(QGL::SampleBuffers), parent )
    {
        m_timer = new QTimer( this );
        m_timer->setSingleShot( false );
        connect( m_timer, SIGNAL(timeout()), this, SLOT(updateGL()) );
        m_timer->start( 7 );

        setWindowTitle( "NeHe Lesson 6" );
    }

    GLWidget::~GLWidget()
    {
        glDeleteTextures( 6, m_textures );
    }

    void GLWidget::initializeGL()
    {
        glShadeModel( GL_SMOOTH );  // Enable smooth shading
        qglClearColor( Qt::black );
        glClearDepth( 1.0f );   // Depth buffer setup
        glEnable( GL_DEPTH_TEST );
        glEnable( GL_TEXTURE_2D );
        glDepthFunc( GL_LEQUAL );
        glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );

        loadTextures();
    }

    void GLWidget::loadTextures()
    {
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

        m_textures[0] = bindTexture( QPixmap(":/img/scifi.bmp") );
        m_textures[1] = bindTexture( QPixmap(":/img/scifi2.bmp") );
        m_textures[2] = bindTexture( QPixmap(":/img/scifi3.bmp") );
        m_textures[3] = bindTexture( QPixmap(":/img/scifi4.bmp") );
        m_textures[4] = bindTexture( QPixmap(":/img/scifi5.bmp") );
        m_textures[5] = bindTexture( QPixmap(":/img/scifi6.bmp") );
    }

    void GLWidget::drawCube()
    {
        // Front face
        glBindTexture( GL_TEXTURE_2D, m_textures[0] );
        glBegin( GL_QUADS );
            glNormal3f( 0.0f, 0.0f, 1.0f );
            glTexCoord2f( 0.0f, 0.0f ); glVertex3f(-1.0f,-1.0f, 1.0f ); // Bottom left
            glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 1.0f,-1.0f, 1.0f ); // Bottom right
            glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.0f, 1.0f, 1.0f ); // Top right
            glTexCoord2f( 0.0f, 1.0f ); glVertex3f(-1.0f, 1.0f, 1.0f ); // Top left
        glEnd();

        // Back face
        glBindTexture( GL_TEXTURE_2D, m_textures[1] );
        glBegin( GL_QUADS );
            glNormal3f( 0.0f, 0.0f, -1.0f );
            glTexCoord2f( 1.0f, 0.0f ); glVertex3f(-1.0f,-1.0f,-1.0f ); // Bottom right
            glTexCoord2f( 1.0f, 1.0f ); glVertex3f(-1.0f, 1.0f,-1.0f ); // Top right
            glTexCoord2f( 0.0f, 1.0f ); glVertex3f( 1.0f, 1.0f,-1.0f ); // Top left
            glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 1.0f,-1.0f,-1.0f ); // Bottom left
        glEnd();

        // Top Face
        glBindTexture( GL_TEXTURE_2D, m_textures[2] );
        glBegin( GL_QUADS );
            glNormal3f( 0.0f, 1.0f, 0.0f );
            glTexCoord2f( 0.0f, 1.0f ); glVertex3f(-1.0f, 1.0f,-1.0f ); // Top left
            glTexCoord2f( 0.0f, 0.0f ); glVertex3f(-1.0f, 1.0f, 1.0f ); // Bottom left
            glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 1.0f, 1.0f, 1.0f ); // Bottom right
            glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.0f, 1.0f,-1.0f ); // Top right
        glEnd();

        // Bottom Face
        glBindTexture( GL_TEXTURE_2D, m_textures[3] );
        glBegin( GL_QUADS );
            glNormal3f( 0.0f, -1.0f, 0.0f );
            glTexCoord2f( 1.0f, 1.0f ); glVertex3f(-1.0f,-1.0f,-1.0f ); // Top right
            glTexCoord2f( 0.0f, 1.0f ); glVertex3f( 1.0f,-1.0f,-1.0f ); // Top left
            glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 1.0f,-1.0f, 1.0f ); // Bottom left
            glTexCoord2f( 1.0f, 0.0f ); glVertex3f(-1.0f,-1.0f, 1.0f ); // Bottom right
        glEnd();

        // Right face
        glBindTexture( GL_TEXTURE_2D, m_textures[4] );
        glBegin( GL_QUADS );
            glNormal3f( 1.0f, 0.0f, 0.0f );
            glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 1.0f,-1.0f,-1.0f ); // Bottom right
            glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.0f, 1.0f,-1.0f ); // Top right
            glTexCoord2f( 0.0f, 1.0f ); glVertex3f( 1.0f, 1.0f, 1.0f ); // Top left
            glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 1.0f,-1.0f, 1.0f ); // Bottom left
        glEnd();

        // Left Face
        glBindTexture( GL_TEXTURE_2D, m_textures[5] );
        glBegin( GL_QUADS );
            glNormal3f( -1.0f, 0.0f, 0.0f );
            glTexCoord2f( 0.0f, 0.0f ); glVertex3f(-1.0f,-1.0f,-1.0f ); // Bottom left
            glTexCoord2f( 1.0f, 0.0f ); glVertex3f(-1.0f,-1.0f, 1.0f ); // Bottom right
            glTexCoord2f( 1.0f, 1.0f ); glVertex3f(-1.0f, 1.0f, 1.0f ); // Top right
            glTexCoord2f( 0.0f, 1.0f ); glVertex3f(-1.0f, 1.0f,-1.0f ); // Top left
        glEnd();
    }

    void GLWidget::paintGL()
    {
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        glLoadIdentity();
        glTranslatef( 0.0f, 0.0f, -5.0f );
        glRotatef( m_xrot, 1.0f, 0.0f, 0.0f );
        glRotatef( m_yrot, 0.0f, 1.0f, 0.0f );
        glRotatef( m_zrot, 0.0f, 0.0f, 1.0f );
        drawCube();

        m_xrot += 0.3f;
        m_yrot += 0.2f;
        m_zrot += 0.4f;
    }

    void GLWidget::resizeGL( int width, int height )
    {
        if( height == 0 )
            height = 1;

        glViewport( 0, 0, width, height );
        glMatrixMode( GL_PROJECTION );
        glLoadIdentity();
        gluPerspective( 45.0f, static_cast<GLfloat>(width)/height, 0.1f, 100.0f );
        glMatrixMode( GL_MODELVIEW );
        glLoadIdentity();
    }
4

0 に答える 0