Using QImage with OpenGL

前端 未结 3 1505
一整个雨季
一整个雨季 2020-12-09 21:19

I\'ve very recently picked up Qt and am using it with OpenGL The thing though is that when moving my SDL code to Qt and changing the texture code to use QImage it stops work

相关标签:
3条回答
  • 2020-12-09 21:26

    I have similar code that works but uses glTexSubImage2D :

    void Widget::paintGL() 
    {
        glClear (GL_COLOR_BUFFER_BIT);       
        glDisable(GL_DEPTH_TEST);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();        
        gluOrtho2D(0,win.width(),0,win.height());
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();        
        glEnable(GL_TEXTURE_2D);
    
        glBindTexture(GL_TEXTURE_2D,texture); 
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0 , image.width(), image.height(),  glFormat, glType, image.bits() );       
        glBegin(GL_QUADS);   // in theory triangles are better
        glTexCoord2i(0,0); glVertex2i(0,win.height());
        glTexCoord2i(0,1); glVertex2i(0,0);
        glTexCoord2i(1,1); glVertex2i(win.width(),0);
        glTexCoord2i(1,0); glVertex2i(win.width(),win.height());
        glEnd();             
    
        glFlush();
    }
    
    
    void Widget::initializeGL() 
    {
        glClearColor (0.0,0.0,0.0,1.0);
        glDisable(GL_DEPTH_TEST);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();        
        gluOrtho2D(0,win.width(),0,win.height());
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();        
    
        glEnable(GL_TEXTURE_2D);
        glGenTextures(3,&texture);
        glBindTexture(GL_TEXTURE_2D,texture);       
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);          
        glBindTexture(GL_TEXTURE_2D,texture);               
        glTexImage2D(GL_TEXTURE_2D, 0, glFormat, image.width(), image.height(), 0, glFormat, glType, NULL );    
    
        glDisable(GL_TEXTURE_2D);
    }
    

    And a few perfomance tweaks in the ctor

    void Widget::setDisplayOptions()
    {
        glFormat = GL_RGB;  //  QImage RGBA is BGRA
        glType = GL_UNSIGNED_BYTE;
    
        QGL::setPreferredPaintEngine(QPaintEngine::OpenGL2);
    
        QGLFormat glFmt;
        glFmt.setSwapInterval(1); // 1= vsync on 
        glFmt.setAlpha(GL_RGBA==glFormat);
        glFmt.setRgba(GL_RGBA==glFormat); 
        glFmt.setDoubleBuffer(true); // default
        glFmt.setOverlay(false);
        glFmt.setSampleBuffers(false);
        QGLFormat::setDefaultFormat(glFmt);
    
        setAttribute(Qt::WA_OpaquePaintEvent,true);
        setAttribute(Qt::WA_PaintOnScreen,true);        
    }
    
    0 讨论(0)
  • 2020-12-09 21:26

    It looks like your problem is not here, as I have no problem with the following code. You should check your GL init and display setup.

    Have you a glEnable(GL_TEXTURE_2D) somewhere ?

    Also note glTexCoord2f must be before glVertex2f.

    #include <GL/glut.h>
    #include <QtOpenGL/qgl.h>
    #include <iostream>
    
    GLuint texture[1] ;
    
    void LoadGLTextures( const char * name )
    {
        QImage img;
        if( ! img.load( name ) )
        {
            std::cerr << "error loading " << name << std::endl ;
            exit( 1 );
        }
    
        QImage GL_formatted_image;
        GL_formatted_image = QGLWidget::convertToGLFormat(img);
        if( GL_formatted_image.isNull() )
        {
            std::cerr << "error GL_formatted_image" << std::endl ;
            exit( 1 );
        }
    
        glGenTextures(1, texture);
        glBindTexture(GL_TEXTURE_2D, texture[0]);
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA,
                GL_formatted_image.width(), GL_formatted_image.height(),
                0, GL_RGBA, GL_UNSIGNED_BYTE, GL_formatted_image.bits() );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 
    }
    
    void resize(int Width, int Height)
    {
        glViewport( 0 , 0 , Width , Height );
    }
    
    void draw()
    {
        glClearColor( 0.0f, 0.0f, 0.0f, 0.0f);
        glClear( GL_COLOR_BUFFER_BIT );
    
        gluOrtho2D( -1 , 1 , -1 , 1 );
    
        glMatrixMode( GL_MODELVIEW );
        glLoadIdentity();
    
        glShadeModel( GL_FLAT );
    
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, texture[0]);
    
        glBegin(GL_TRIANGLES);
        glTexCoord2f( 1.0f, 0.0f);
        glVertex2f( 1.0f, 0.0f);
        glTexCoord2f( 0.0f, 1.0f);
        glVertex2f( 0.0f, 1.0f);
        glTexCoord2f( 0.0f, 0.0f);
        glVertex2f( 0.0f, 0.0f);
        glEnd();
    
        glutSwapBuffers();
    }
    
    int main(int argc, char **argv) 
    {  
        glutInit(&argc, argv);  
        glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA );  
        glutInitWindowSize(640, 480);
    
        glutCreateWindow("Texture"); 
    
        LoadGLTextures( "star.png" );
    
        glutDisplayFunc( & draw );  
        glutReshapeFunc( & resize );
        glutMainLoop();  
    
        return 1;
    }
    
    0 讨论(0)
  • 2020-12-09 21:33

    This is my solution for conversion from Qt to GL This also can work in reverse with little changes; Cheers -- Daimon

    void Image::Convert32bitARGBtoRGBA()
    {
        if(!isQtImage()) return;
        QImage& q = *(m_data->image);
        U32 count=0, max=(U32)(q.height()*q.width());
        U32* p = (U32*)(q.bits());
        U32 n;
        while( count<max )
        {
            n = p[count];   //n = ARGB
            p[count] =  0x00000000 |
                    ((n<<8)  & 0x0000ff00) |
                    ((n<<8)  & 0x00ff0000) |
                    ((n<<8)  & 0xff000000) |
                    ((n>>24) & 0x000000ff);
                    // p[count] = RGBA
            count++;
        }
    }
    
    void Image::Convert32bitRGBAtoARGB()
    {
        if(!isQtImage()) return;
        QImage& q = *(m_data->image);
        U32 count=0, max=(U32)(q.height()*q.width());
        U32* p = (U32*)(q.bits());
        U32 n;
        while( count<max )
        {
            n = p[count];   //n = RGBA
            p[count] =  0x00000000 |
                    ((n>>8)  & 0x000000ff) |
                    ((n>>8)  & 0x0000ff00) |
                    ((n>>8)  & 0x00ff0000) |
                    ((n<<24) & 0xff000000);
                    // p[count] = ARGB
            count++;
        }
    }
    
    0 讨论(0)
提交回复
热议问题