Fixed models using other model's textures bug#319
Fixed models using other model's textures bug#319CMDR-JohnAlex wants to merge 14 commits intoJoeyDeVries:masterfrom
Conversation
When you load a model that does not have a diffuse, specular, normal or height map, it will use one from the previously rendered model.
|
It is a good practice. Although, I feel it may decrease performance because you're having to iterate through each textures and use an expensive set and bind function. |
|
Hello @JG-Adams. Now that I look at my code again it does look like there would be a performance decrease when using my workaround. The more textures loaded, the more the expensive set and bind functions are used... 🤦 Thank you for letting me know your workaround to this issue but I have one question. How did you implement the default image solution? Thank you! |
|
I just updated my pull request to show my current solution. Probably not tutorial grade code so I don't expect it to be merged. |
Looks like you can't create a texture ID with no data at all, otherwise you can get graphical artifacts like with the sponza plants. Now I am binding the texture then creating a texture with no (nullptr) data.
It look almost identical to mine actually! :) Almost got it. |
|
Static function doesn't work the way I thought it would. But it's still fine. Put this in private: Put this in the constructor:if (notex==0) In function TextureFromFile(): Your new code where you do this: Where I put <--- replace this Then, below, in the existing code like the one above but has: texture.id = TextureFromFile(str.C_Str(), this->directory, gamma); And that's it! |
|
Check this for reference. #323 |
|
From my understanding, those artefacts happen here: if (notex == 0)
{
uint8_t data[3] = { 255,255,255 }; // <-- This
glGenTextures(1, ¬ex);
glBindTexture(GL_TEXTURE_2D, notex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}We have no alpha channel/no transparency so those fragments won't get discarded and therefor we see those strange artefacts? I just tested by changing |
|
Ok, so after a while of messing around I fixed the sponza plant issue and I'm just adding my changes to github right now. Let me know if this works for you too and thank you for your help! 😃 |
Added a default for no specular maps instead of using the diffuse default. Personally I don't what anything with no specular map to be automatically bright.
|
Yay! Teamwork! Hmm, thinking about it though. This might cause confusion. Like, "why isn't there any specular?" if they didn't know it was set to 0. |
|
Yes! Teamwork! I didn't know I was good at working with other devs. I added specular as 255 on github again as the, "why isn't there any specular?" scenario is possible. |
After slapping some std::cout statements everywhere I found that once the program loads a default diffuse, specular or normal texture it would use that again for the next missing texture! So for example if a model doesn't have a specular or normal, it will check if the specular map is loaded, and because it is not it will use the default specular map for the missing specular map and the texture.path will be NO_TEXTURE. When we check if the normal map is already loaded it will see there is a texture already loaded with the name NO_TEXTURE so it will just use that texture thinking its the specular map it wanted, when in reality that is a specular map, not a normal map! Same goes if a model doesn't have any textures, it will use the default texture for diffuse, specular and normal.
|
I already wrote this in the commit message but here it is: After slapping some std::cout statements everywhere I found that once the program loads a default diffuse, specular or normal texture it would use that again for the next missing texture! |
Before we used the specular map for things that aren't diffuse and specular maps. That would mean height maps would use the specular map and if emissive and other maps are added to the code, they too would use the specular map.
|
Oh! woops! good find! |
includes/learnopengl/model.h
Outdated
| class Model | ||
| { | ||
| public: | ||
| static unsigned int defaultDiffuse, defaultSpecular, defaultNormal, defaultOther; |
There was a problem hiding this comment.
This can function in the private section. Unless you have external texture you want to use.
There's a way for that too!
There was a problem hiding this comment.
The issue with this is the textureFromFile() function is outside of the model class so when it tries to return Model::defaultDiffuse it can't because that is a private member.
|
Having a default specular and others may not be necessary and can lead to same confusion. |
Ok, I'll return the code to using a white specular for everything else. Edit: Sorry it was taking me a while to do things, I'm a little busy on my end. |



Hello! First of all I love your tutorials SO MUCH! Thank you for them!
I noticed that when you load a model that does not have a diffuse, specular, normal or height map it will use the one from the previously rendered model. What I have here was my simple fix to the issue. This should also be able to close issue #317 .