Aleksander Fimreite
Aleksander Fimreite

Reputation: 1449

Texture rendering bug?

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);



    }
}

Upvotes: 0

Views: 1043

Answers (1)

Andon M. Coleman
Andon M. Coleman

Reputation: 43369

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.

Upvotes: 1

Related Questions