Using QImage with OpenGL

ⅰ亾dé卋堺 提交于 2019-11-28 08:38:15
Martin Beckett

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);        
}
Daimon

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++;
    }
}

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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!