Hi,
I am trying to texture a scene I've written in C++ utilizing OpenGL. Purposeful I have written the following class for handling textures:
class Texture
{
private:
Texture (const GLuint nTextureID) : m_nTextureID (nTextureID) { }
public:
~Texture () { glDeleteTextures (1, &m_nTextureID); }
public:
static Texture* loadFromBMP (const std::string& sFile);
GLuint getID () const
{
return m_nTextureID;
}
void setActive () const
{
glBindTexture (GL_TEXTURE_2D, m_nTextureID);
}
private:
const GLuint m_nTextureID;
};
The function for loading a texture from file is defined as follows:
Texture* Texture::loadFromBMP (const std::string& sFile)
{
std::ifstream fIn (sFile.c_str (), std::ios::in | std::ios::binary);
if (fIn.good ())
{
try
{
// read header
unsigned short nFormat;
fIn.read (reinterpret_cast <char*> (&nFormat), 2);
if (nFormat != 19778)
{
std::cerr << "(EE) Failed to read: " << sFile << std::endl;
std::cerr << "(EE) Not a Windows Bitmap." << std::endl;
std::cerr << std::endl;
fIn.close ();
return NULL;
}
fIn.seekg (18);
signed int nWidth, nHeight;
fIn.read (reinterpret_cast <char*> (&nWidth), 4);
fIn.read (reinterpret_cast <char*> (&nHeight), 4);
// compute body size
const unsigned int nBodySize = 3 * nWidth * nHeight;
// read planes
unsigned short nPlanes;
fIn.read (reinterpret_cast <char*> (&nPlanes), 2);
// read bits per pixel
unsigned short nBPP;
fIn.read (reinterpret_cast <char*> (&nBPP), 2);
// ensure format is supported
if (nPlanes != 1 || nBPP != 24)
{
std::cerr << "(EE) Failed to read: " << sFile << std::endl;
std::cerr << "(EE) Unsupported format: " << nBPP << " bpp, " << nPlanes << " plane(s)" << std::endl;
std::cerr << "(EE) Only bitmaps with 24 color depth and 1 plane are supported." << std::endl;
std::cerr << std::endl;
fIn.close ();
return NULL;
}
// seek past the rest of the header
fIn.seekg (54);
// read body data
char* const pcData = new char [nBodySize];
fIn.read (pcData, nBodySize);
// we are done reading the file
fIn.close ();
// reverse byte order (convert 'BGR' to 'RGB')
for (unsigned int j = 0; j < nBodySize ; j += 3)
{
pcData [j] ^= pcData [j + 2];
pcData [j + 2] ^= pcData [j];
}
// now we need to create the texture
GLuint nTextureID;
glGenTextures (1, &nTextureID);
glBindTexture (GL_TEXTURE_2D, nTextureID);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// 2D texture, level of detail 0 (normal), 3 components (red, green, blue), x size, y size,
// border 0 (normal), rgb color data, unsigned byte data, and finally the data itself
glTexImage2D (GL_TEXTURE_2D, 0, 3, nWidth, nHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, pcData);
delete [] pcData;
// finish
return new Texture (nTextureID);
}
catch (...)
{
fIn.close ();
std::cerr << "(EE) Failed to read: " << sFile << std::endl;
std::cerr << "(EE) Unknown error." << std::endl;
std::cerr << std::endl;
return NULL;
}
}
else
{
fIn.close ();
std::cerr << "(EE) Failed to read: " << sFile << std::endl;
std::cerr << "(EE) Either file not found or not allowed to open for reading." << std::endl;
std::cerr << std::endl;
return NULL;
}
}
So far. When the program is initialized I call these:
static Texture* s_aTextures []; // member of a class named C
// [...]
Texture* C::s_aTextures [] = { NULL, NULL, NULL, NULL, NULL, NULL };
// [...]
s_aTextures [0] = Texture::loadFromBMP ("test1.bmp");
s_aTextures [1] = Texture::loadFromBMP ("test2.bmp");
s_aTextures [2] = Texture::loadFromBMP ("test3.bmp");
s_aTextures [3] = Texture::loadFromBMP ("test4.bmp");
s_aTextures [4] = Texture::loadFromBMP ("test5.bmp");
s_aTextures [5] = Texture::loadFromBMP ("test6.bmp");
When 'pre-rendering' the scene into a display-list I call
setActive on the various elements of the array:
s_aTextures [2] -> setActive ();
The actual problem: Everything that I render is being drawn with one and the same texture, although I call
setActive on different textures. To be precisely, everything is being rendered with the texture I have created (loaded) lastly - Dont't misunderstand me, it's not the texture I call
setActive upon lastly. I have no idea what I could have done wrong. The local variable
nTextureID in
Texture::loadFromBMP has a correct value, namely an unique one everytime the function is called. Anyone got an idea?
Thanks in advance