Вершинные массивы Qt не работают с QImage - PullRequest
2 голосов
/ 18 марта 2011

Я начну с извинения за длину вопроса.Я полагаю, что допустил небольшую глупую ошибку, но, поскольку я совершенно не могу ее найти, я решил опубликовать весь соответствующий код на всякий случай.

Я наконец-то получил загрузку текстуры, работающую с использованием 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 ]

2 голосов
/ 25 марта 2011

Одна из возможностей заключается в том, что проблема связана с вызовом glVertexCoordPointer перед вызовом glTexCoordPointer.Странные вещи случаются, когда вы задаете координату текстуры после координаты вершины.Я знаю, что это верно для рисования одной вершины с текстурной координатой.Я не уверен, правда ли это с массивами.

Несколько других вещей ...

Вы пытались использовать QPixMap вместо QImage?Я сомневаюсь, что это ответ на вашу проблему, так как похоже, что текстура применяется к первому квадру правильно.

Есть два вызова bindTexture.

Вы пробовали просто нарисовать вершины (без текстуры) во второй части кода?

Наконец, вы получаете какие-либо предупреждения компилятора?

0 голосов
/ 18 марта 2011

То, как вы размещаете манипуляции с состоянием 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.

Просто для целей отладки попробуйте изменить тип текстурных координат на плавающие.

...