Qt Vertex Arrays不能与QImage一起使用

时间:2011-03-18 19:06:16

标签: c++ qt opengl vertex-array

我首先要为问题的长度道歉。我相信我犯了一些小的,愚蠢的错误,但由于我完全找不到它,我决定发布所有相关代码以防万一。

我终于使用QImage进行纹理加载,并且能够立即渲染纹理。 但是,顶点数组不起作用,我不知道为什么。 最明显的事情,比如“你启用了顶点数组和纹理坐标数组吗?”可能不是答案。我将发布初始化代码。

这是init函数:

    /* general OpenGL initialization function */
    int initGL()
    {

        glShadeModel(GL_SMOOTH);                            // Enable Smooth Shading
        glClearColor(0, 0, 0, 1);               // Black Background
        glEnable ( GL_COLOR_MATERIAL );
        glColorMaterial ( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );


        glDisable(GL_DEPTH_TEST);


//ENABLED VERTEX ARRAYS AND TEXTURE COORDINATE ARRAYS       
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glEnableClientState(GL_VERTEX_ARRAY);

//ENABLED 2D TEXTURING
        glEnable ( GL_TEXTURE_2D );
        glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );

        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

//seed random
        srand(time(NULL));


        return( TRUE );
    }

我有初始化,调整大小和绘制由QGLWidget调用的函数(它本身只是一个调用实际工作函数的骨架)

纹理加载功能:

GLuint LoadGLTextures( const char * name )
 {
     //unformatted QImage
     QImage img;
     //load the image from a .qrc resource
     if(!img.load(":/star.bmp"))
     {
         qWarning("ERROR LOADING IMAGE");
     }

     //an OpenGL formatted QImage
     QImage GL_formatted_image;
     GL_formatted_image = QGLWidget::convertToGLFormat(img);

     //error check
     if(GL_formatted_image.isNull())
         qWarning("IMAGE IS NULL");
     else
         qWarning("IMAGE NOT NULL");


     //texture ID
     GLuint _textures[1];


     //enable texturing
     glEnable(GL_TEXTURE_2D);
     //generate textures
     glGenTextures(1,&_textures[0]);
     //bind the texture
     glBindTexture(GL_TEXTURE_2D,_textures[0]);
     //texture parameters
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glBindTexture(GL_TEXTURE_2D,_textures[0]);
     //generate 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());




     glBindTexture(GL_TEXTURE_2D,_textures[0]);

     //return the texture ID
     return _textures[0];
}

这是绘图代码:

//this does draw

//get the texture ID
    GLuint tex_id = LoadGLTextures(":/star.png");

        glBindTexture(GL_TEXTURE_2D, tex_id); // Actually have an array of images



        glColor3f(1.0f, 0.0f, 0.5f);
        glBegin(GL_QUADS);
            glTexCoord2f(1.0f, 0.0f);glVertex2f(1.0f, 0.0f);
            glTexCoord2f(1.0f, 1.0f);glVertex2f(1.0f, 1.0f);
            glTexCoord2f(0.0f, 1.0f);glVertex2f(0.0f, 1.0f);
            glTexCoord2f(0.0f, 0.0f);glVertex2f(0.0f, 0.0f);
        glEnd();


//this does not draw

        //translations code
        glLoadIdentity();
        glTranslatef(-1.0f, 0.0f, 0.0f);
        //bind the texture
        glBindTexture(GL_TEXTURE_2D, tex_id);
        //set color state
        glColor4f(0.0f, 1.0f, 0.0f, 0.5);

        //vertices to be rendered
        static GLfloat vertices[] =
        {
            1.0f, 0.0f,
            1.0f, 1.0f,
            0.0f, 1.0f,
            0.0f, 0.0f

        };

        static GLshort coord_Data[] =
        {
        1, 0,
        1, 1,
        0, 1,
        0, 0


        };

        //bind the texture
        glBindTexture(GL_TEXTURE_2D, tex_id);
        //pointer to the vertex array
        glVertexPointer(2, GL_FLOAT, 0, vertices);
        //texture coordinate pointer
        glTexCoordPointer(2, GL_SHORT, 0, coord_Data);

        //draw the arrays
        glDrawArrays(GL_QUADS, 0, 4);

感谢您的帮助, Dragonwrenn

2 个答案:

答案 0 :(得分:2)

一种可能性是问题源于在调用glTexCoordPointer之前调用glVertexCoordPointer。在顶点坐标后指定纹理坐标时会发生奇怪的事情。我知道这对于使用纹理坐标绘制单个顶点是正确的。我不确定数组是否属实。

其他一些事情......

您是否尝试过使用QPixMap而不是QImage?我怀疑这是你的问题的答案,因为它听起来像纹理适当地应用于第一个四边形。

有两次调用bindTexture。

您是否尝试过在代码的第二部分绘制顶点(没有纹理)?

最后,你得到任何编译器警告吗?

答案 1 :(得分:0)

您放置OpenGL状态操作的方式很难跟踪事物。按需设置OpenGL状态是个好主意。所以

移动此

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_CORRD_ARRAY);

之前

    //bind the texture
    glBindTexture(GL_TEXTURE_2D, tex_id);
    glVertexPointer(2, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_SHORT, 0, coord_Data);

    //draw the arrays
    glDrawArrays(GL_QUADS, 0, 4);

您也应该从initGL移动其他代码。

在向glTexImage提供数据之前属于纹理加载器

glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );

属于绘图功能的开头:

glShadeModel(GL_SMOOTH);
glClearColor(0, 0, 0, 1);
glEnable( GL_COLOR_MATERIAL );
glColorMaterial ( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );

glDisable(GL_DEPTH_TEST);

遵循该方案,您还应在绘图功能中设置视口和投影矩阵。我只是在说这个,因为大多数教程都采用不同的方式,这使得人们认为这是正确的方法。技术上也是投影和视口以及按需状态。

每次绘制调用都不应重新加载纹理。请注意,通过绘图处理程序按需初始化纹理是一个好主意,您应该在纹理封装类中添加一些标志,告诉我,如果引用的纹理已经可用于OpenGL。

仅出于调试目的,请尝试将纹理坐标的类型更改为浮动。