2

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

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

这是初始化函数:

    /* 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

4

2 回答 2

2

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

其他几件事...

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

bindTexture 有两个调用。

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

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

于 2011-03-25T01:11:55.347 回答
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。

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

于 2011-03-18T19:19:38.283 回答