qt - 在OpenGL中使用QImage

标签 qt opengl-es textures qimage

我最近刚拿起Qt并将其与OpenGL一起使用
但是,问题是,将我的SDL代码移至Qt并更改纹理代码以使用QImage时,它将停止工作。

该图像确实正确加载,如通过错误检查代码所示。

谢谢!

附注:请不要建议我使用glDrawPixels,我需要解决当前的问题。原因之一是1.速度慢2. android(此代码最终可能会在其上运行)是OpenGL ES,不支持glDrawPixels

这是代码:

//original image
QImage img;
if(!img.load(":/star.png"))
{
    //loads correctly
    qWarning("ERROR LOADING IMAGE");
}

//array for holding texture ID
GLuint texture[1];

//get the OpenGL-friendly image
QImage GL_formatted_image;
GL_formatted_image = QGLWidget::convertToGLFormat(img);

//make sure its not null
if(GL_formatted_image.isNull())
    qWarning("IMAGE IS NULL");
else
    qWarning("IMAGE NOT NULL");

//generate the texture name
glGenTextures(1, texture);

//bind the texture ID
glBindTexture(GL_TEXTURE_2D, texture[0]);

//generate the texture
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() );

//texture parameters
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);



//draw the texture
glPushMatrix();
glTranslatef(-2.0f, 0.0f, 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_TRIANGLES);
    glVertex2f(1.0f, 0.0f);
 glTexCoord2f(1.0f, 0.0f);
    glVertex2f(0.0f, 1.0f);
 glTexCoord2f(0.0f, 1.0f);
    glVertex2f(0.0f, 0.0f);
 glTexCoord2f(0.0f, 0.0f);
glEnd();
glPopMatrix();

这是SDL的原始纹理加载功能:
GLuint loadTexturewithSDL(const char* FILE, GLenum texture_format)
{
    GLuint texture;         // This is a handle to our texture object
    SDL_Surface *surface;   // This surface will tell us the details of the image
    GLint  nOfColors;



    if ( (surface = SDL_LoadBMP(FILE)) ) {

    // Check that the image's width is a power of 2
    if ( (surface->w & (surface->w - 1)) != 0 ) {
        printf("warning: image's width is not a power of 2\n");
    }

    // Also check if the height is a power of 2
    if ( (surface->h & (surface->h - 1)) != 0 ) {
        printf("warning: image's height is not a power of 2\n");
    }

        // get the number of channels in the SDL surface
        nOfColors = surface->format->BytesPerPixel;
        if (nOfColors == 4)     // contains an alpha channel
        {
                if (surface->format->Rmask == 0x000000ff)
                        texture_format = GL_RGBA;
                else
                        texture_format = GL_BGRA;
        } else if (nOfColors == 3)     // no alpha channel
        {
                if (surface->format->Rmask == 0x000000ff)
                        texture_format = GL_RGB;
                else
                        texture_format = GL_BGR;
        } else {
                printf("warning: the image is not truecolor..  this will probably break\n");
                // this error should not go unhandled
        }

    // Have OpenGL generate a texture object handle for us
    glGenTextures( 1, &texture );

    // Bind the texture object
    glBindTexture( GL_TEXTURE_2D, texture );

    // Set the texture's stretching properties
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

    // Edit the texture object's image data using the information SDL_Surface gives us
    glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
                      texture_format, GL_UNSIGNED_BYTE, surface->pixels );
}
else {
    printf("SDL could not load image %s\n", SDL_GetError());
    SDL_Quit();
    return 1;
}

// Free the SDL_Surface only if it was successfully created
if ( surface ) {
    SDL_FreeSurface( surface );
}

    return texture;
}

最佳答案

我有类似的代码可以工作,但使用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);
}
还有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);        
}
中的一些性能调整

关于qt - 在OpenGL中使用QImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5335218/

相关文章:

opengl - 二次幂纹理的效率有多高?

c++ - 所有 .txt 文件的列表

c++ - ft2build.h : No such file or directory - Freetype 2. 6

Qt Creator-意见和想法

iphone - 如何在不使用抗锯齿的情况下使盒子的边缘平滑?

android - 混合和 Z 缓冲区在 2 个独立的着色器程序之间共享?

c++ - 如何创建自定义引用容器?

android - 将自定义过滤器应用于相机输出

c++ - Direct3d 绘制 2d Sprite 。缩放问题

c++ - 数组/vector 中的 SFML 2.0 c++ Sprite