Reputation: 2271
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!
Upvotes: 0
Views: 129
Reputation: 162164
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.
Upvotes: 2