简体   繁体   中英

Function to load textures not working correctly

So I wrote a helper function that just loads a png file disc and loads it into an OpenGL shader.

This all works fine and well until I try to load multiple textures. The problem that I run into is the fact it seems to overrite all previous textures each time. I have no idea why this is happening. If the code I am providing isn't enough, the full source is posted here

Here is the loadTexture function (resides in Helper.cpp)

GLuint loadTexture(const GLchar* filepath, GLuint& width, GLuint& height)
{
    // image vector.
    vector<GLubyte> img;

    // decodes the image to img
    decode(img, filepath, width, height);

    // if the image is empty return
    if (img.size() == 0)
    {
        std::cout << "Bad Image" << std::endl;
        system("pause");
        return 0;
    }
    // return value
    GLuint ret;

    // gen textures
    glGenTextures(1, &ret);

    // bind the ret to GL_TEXTURE_2D so everyting using GL_TEXTURE_2D referrs to ret
    glBindTexture(GL_TEXTURE_2D, ret);

    // set parameters. Current filtering techunique is GL_LINEAR http://www.arcsynthesis.org/gltut/Texturing/Tut15%20Magnification.html
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // copy the data to the texture associated with ret. 
    // format is RGBA internally and externally, and the size is unsigned char, which is unsigned byte
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &img[0]);

    return ret;

}

The decode method saves the image to img and stores the width and height to width and height respectively.

If there is something that I am missing please tell me.

Thanks for any help I can get!

When something doesn't work with OpenGL, always look in the drawing code first. In your draw function (I hate Dropbox, BTW, first have to download that shit so that I can view it) there's this:

        GLuint uniID = glGetUniformLocation(program, "tex");

        glActiveTexture(GL_TEXTURE0);
        glUniform1i(textures[idx], 0);

That's your problem right there. textures[idx] contains the textureIDs. But the texture ID does not go into a shader uniform at all. The first parameter to glUniform… is the so called "location index" of the shader variable. Right above the uniform location of a shader variable called tex is queried. That is what goes into the uniform call. The value is the number of the active texture unit.

To select the actual texture to be used, you have to bind the right texture to the right texture unit. Your original code lacked to bind the desired texture when it was needed.

Use this code:

glUseProgram(program)
GLuint uniID = glGetUniformLocation(program, "tex");
for(…) {
    /* ... */
    int const unit = 0; // just for illustration
    glUniform1i(uniID, unit);
    glActiveTexture(GL_TEXTURE0 + unit);
    glBindTexture(GL_TEXTURE_2D, textures[idx]);
    /* draw stuff ...*/
}

BTW: Textures are not loaded into shaders.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM