C++ Qt顶点数组不使用QImage

C++ Qt顶点数组不使用QImage,c++,qt,opengl,vertex-array,C++,Qt,Opengl,Vertex Array,首先,我要为问题的长度道歉。我相信我犯了一些小而愚蠢的错误,但由于我完全找不到它,我决定发布所有相关代码以防万一 我最终使用QImage实现了纹理加载,并且能够以即时模式渲染纹理。 然而,顶点数组不工作,我不知道为什么。 最明显的问题,如“是否启用了顶点阵列和纹理坐标阵列?”可能不是答案。我将发布初始化代码 以下是init函数: /* general OpenGL initialization function */ int initGL() { glS

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

我最终使用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 );
    }
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];
}
我有QGLWidget调用的初始化、调整大小和绘制函数(它本身只是一个调用实际工作函数的框架)

纹理加载功能:

    /* 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 );
    }
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

按照您放置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,则应向纹理封装类添加一些标志


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

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

其他一些事情

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

有两个对bindTexture的调用

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


最后,您是否收到任何编译器警告?

另请参见1。尝试将其更改为QPixmap。行为没有变化(立即模式四边形显示良好,顶点阵列不显示)2+1用于在顶点坐标之前提醒我纹理坐标(尽管问题仍未解决)3。立即模式绘图将正确继续,顶点阵列不会4。5没有编译器警告。感谢提醒您使用纹理绑定,您可以在某些调用之后,特别是在gldrawArray之后,尝试调用glGetError。也许这会对你的问题有所帮助。