0
votes

I'm doing a bachelor project with some freinds, and we've run in to a pretty confusing bug with OpenGL textures. And I'm wondering if there's any knowledge about such things here...

The problem we're having, is that at our laptops (running Intel HD graphics) we can see the textures fine. But if we change it to run at dedicated graphics cards, we can't see the textures. We can't see them at our desktops with dedicated craphics cards either (both AMD and Nvidia).

So, what is up with that? Any ideas?

EDIT: Added texture & render code, not made by me so I don't know 100% how it works. But I think i found everything.

Texture load:

Texture::Texture(const char* imagepath)
{


    textureImage = IMG_Load(imagepath);
    if (!textureImage)
    {
        fprintf(stderr, "Couldn't load %s.\n", imagepath);

    }
    else{
    textureID = 0;

    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    glTexImage2D(GL_TEXTURE_2D,
        0, GL_RGB,
        textureImage->w,
        textureImage->h,
        0,
        GL_RGB,
        GL_UNSIGNED_BYTE,
        textureImage->pixels);
    SDL_FreeSurface(textureImage);

    }
}

Platform VBO:

PlatformVBO::PlatformVBO() {
    glGenBuffers(1, &vboID);
    glGenBuffers(1, &colorID);
    glGenBuffers(1, &texID);
    //glGenBuffers(1, &indID);

    texCoords.push_back(0.0f);
    texCoords.push_back(0.0f);

    texCoords.push_back(1.0f);
    texCoords.push_back(0.0f);

    texCoords.push_back(1.0f);
    texCoords.push_back(1.0f);

    texCoords.push_back(0.0f);
    texCoords.push_back(1.0f);

    //
    indices.push_back(0);
    indices.push_back(1);
    indices.push_back(2);

    indices.push_back(0);
    indices.push_back(2);
    indices.push_back(3);


    bgTexture = new Texture("./Texture/shiphull.png");
    platform = new Texture("./Texture/Abstract_Vector_Background.png");
    // Give the image to OpenGL


    glBindBuffer(GL_ARRAY_BUFFER, texID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) *texCoords.size() / 2, &texCoords, GL_STATIC_DRAW);


    //glBindBuffer(GL_ARRAY_BUFFER, texID);
    //glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) *texCoords.size() / 2, &texCoords, GL_STATIC_DRAW);


}

Update VBO:

void PlatformVBO::setVBO(){
    // Vertices:
    glBindBuffer(GL_ARRAY_BUFFER, vboID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) *vertices.size(), &vertices.front(), GL_STATIC_DRAW);


    glBindBuffer(GL_ARRAY_BUFFER, colorID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) *colors.size(), &colors.front(), GL_STATIC_DRAW);



}

Draw:

void PlatformVBO::drawTexture(){


    if (vertices.size() > 0){
        setVBO();


        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indID);

            //Enable states, and render (as if using vertex arrays directly)
            glEnableClientState(GL_VERTEX_ARRAY);

            glBindBuffer(GL_ARRAY_BUFFER, vboID);
            glVertexPointer(2, GL_FLOAT, 0, 0);

            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            glBindBuffer(GL_ARRAY_BUFFER, texID);
            glTexCoordPointer(2, GL_FLOAT, 0, 0);

            if (bgTexture->GetTexture() >= 0) {
                glEnable(GL_TEXTURE_2D);      // Turn on Texturing
            //  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
                glBindTexture(GL_TEXTURE_2D, bgTexture->GetTexture());
            }

            //Draw the thing!
            glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, &indices[0]);

            //restore the GL state back

            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
            glDisableClientState(GL_VERTEX_ARRAY);

            if (bgTexture->GetTexture() >= 0) {
                glDisable(GL_TEXTURE_2D);      // Turn off Texturing
                glBindTexture(GL_TEXTURE_2D, bgTexture->GetTexture());
            }



            glBindBuffer(GL_ARRAY_BUFFER, 0); //Restore non VBO mode
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);



    }
}
1
"works on intel but doesn't with other vendors" is extremely vague. Try to start a OpenGL debug context and read the debug messages or at least use glGetError in a few spots to try to find out more. If you need more help you should probably post a few more details. - PeterT
There is no errors though. It runs fine, just that we don't see the texture. And yes and I know it a little vague. But that is about the only time I need help as well x) - Aleksander Fimreite
at least provide us with some code on how you upload and bind your textures - PeterT
Why are you creating/populating an IBO and then not using it in your glDrawElements() call (the last parameter should be a byte offset instead of a client-side pointer if you want use a bound IBO)? - genpfault

1 Answers

1
votes

Do not divide your texture coordinate size by 2 (that will cut the coordinates in half), and do not pass the address of the vector (that will give undefined results as there is no guarantee about the memory layout of std::vector).

Use this instead:

glBufferData (GL_ARRAY_BUFFER, sizeof(GLfloat) * texCoords.size(), &texCoords [0], GL_STATIC_DRAW);

Notice how this uses the address of the reference returned by std::vector's operator [] instead? C++03 guarantees the memory used internally for element storage is a contiguous array. Many earlier implementations of the C++ standard library worked this way, but the spec. did not guarantee it. C++11 adds std::vector::data (), which effectively does the same thing, but makes your code require a newer compiler.