I have been trying to load a default texture for my materials when a texture isn't given. Due to some issues with the texture loader that I am using, I have decided to fill the image data array manually to then pass it to the OpenGL functions to be bound. Unfortunately, this results in my models being black meaning the texture wasn't loaded correctly.
Below shows the two different constructors. The first one loads textures from a file (and works) while the second one fills the char buffer with the 255 character (which should be white). The InitTexture() function performs all the OpenGL functions to bind the texture and works fine for the loaded texture, but not my manual buffer.
I've checked to make sure the data is correct, even comparing it with a loaded texture that is just a white image and the values are the same.
The constructor was designed to be used for the initialization of a static variable. Not sure if this would affect how any of the OpenGL functions.
// Texture loaded Constructor - Works Fine
Texture::Texture(const std::string& filename)
{
// Load texture from file
int width, height, numComponents;
unsigned char* imageData = stbi_load(filename.c_str(), &width, &height, &numComponents, 4);
if (imageData == NULL)
std::cerr << "Error: Texture loading failed: " << filename << std::endl;
InitTexture(imageData, width, height);
stbi_image_free(imageData);
}
// Manual Texture Constructor - should be white but isn't
// A 4x4 image should have 16 pixels and each pixel has 4 values (RGBA)
// meaning 64 should be the correct size for the buffer??
Texture::Texture()
{
int height = 4;
int width = 4;
unsigned char* data = new unsigned char[64];
for (int i = 0; i < 64; ++i)
data[i] = 255;
InitTexture(data, width, height);
delete[] data;
}
// This is the initialization of the DefaultDiffuse texture - this is the
// static varible in the Material class
Texture Material::defaultDiffuse = Texture();
The only workaround I've managed to do is to have a static Setter for the diffuse texture and pass it a copy of a loaded texture that is just white.
Please let me know if there is any more information that I can provide. Thank you
Edit:
Here is the InitTexture() function. It is the function that handles all the OpenGL operations of binding and generating the textures.
void Texture::InitTexture(unsigned char* data, const int& width, const int& height, bool mipmap)
{
// Create handle to texture
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// Sets texture wrap mode
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Handles sampling the texture
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Generates the texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
}
Edit 2:
After doing some testing I've found that if instead of InitTexture() being called in the constructor, I call it in a static function that I have to call at the beginning of the main method and for some reason, it works. My guess is that when the OpenGL functions are called when a static member variable is being initialized the buffers aren't being set correctly. Unfortunately, I don't know enough about OpenGL to know when its elements get initialized. Is it possible that the static variables are getting initialized before OpenGL does?