Jump to content
  • Advertisement
Sign in to follow this  
evoid

OpenGL problem with textures

This topic is 3493 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement
I am not a C++ expert but why do you not let the memmber function loadFromBMP update m_nTextureID directly? Im not sure it is the way you do it.

Share this post


Link to post
Share on other sites
Quote:
Original post by mrr
I am not a C++ expert but why do you not let the memmber function loadFromBMP update m_nTextureID directly? Im not sure it is the way you do it.


Actually loadFromBMP does update m_nTextureID directly by calling the constructor of Texture.

Quote:
Original post by AndyEsser
Don't make the Texture class a Static. Try that.


What do you mean? Can you explain that? I don't know what a static class is and as far as I can see I haven't used static classes.

In case you meant making the function loadFromBMP non-static: I tried it and it did not change anything.

Anyway, here are the altered files, in case you want to take a look on them:
texture.cpp: http://pastebin.com/f74e9ac1a
texture.h: http://pastebin.com/f7001a619

Or did you mean making the instances of Texture non-static? I tried that too but also without any effect.

Share this post


Link to post
Share on other sites
In your header file you have commented out the line:

//static Texture* loadFromBMP (const std::string& sFile);

How come?

Have you tried it with just

Texture* loadFromBMP (const std::string& sFile);

And have you checked when doing SetActive that the value in m_nTextureID is different for each texture?

Also, it was this line I meant don't make static:


static Texture* s_aTextures []; // member of a class named C

Share this post


Link to post
Share on other sites
Quote:
Original post by AndyEsser
In your header file you have commented out the line:

//static Texture* loadFromBMP (const std::string& sFile);

How come?

Have you tried it with just

Texture* loadFromBMP (const std::string& sFile);

I had moved the loadFromBMP-functionallity to the Texture::Texture(const std::string&) constructor. So, to answer your question: Yes, I've tried it.

Quote:
Original post by AndyEsser
And have you checked when doing SetActive that the value in m_nTextureID is different for each texture?

Yes, I've checked this. All values are definetly unique.

Quote:
Original post by AndyEsser
Also, it was this line I meant don't make static:

*** Source Snippet Removed ***

OK. As I wrote in my previous post, I've tried making it non-static but had no luck.

Share this post


Link to post
Share on other sites
Apologies, wasn't sure exactly which bit you meant you had tried. Could you show me your rendering routine?

Share this post


Link to post
Share on other sites
Sure, here it is:

void C::draw ()
{
glEnable (GL_TEXTURE_2D);
glColor3ub (230, 230, 230);
glBegin (GL_QUADS);

// front

s_aTextures [0] -> setActive ();
//std::cout << s_aTextures [0] -> getID () << std::endl;
glTexCoord2f (0.0f, 0.0f); glVertex3f (-1.0f, -1.0f, 1.0f);
glTexCoord2f (0.0f, 1.0f); glVertex3f (-1.0f, 1.0f, 1.0f);
glTexCoord2f (1.0f, 1.0f); glVertex3f ( 1.0f, 1.0f, 1.0f);
glTexCoord2f (1.0f, 0.0f); glVertex3f ( 1.0f, -1.0f, 1.0f);

// back

s_aTextures [1] -> setActive ();
//std::cout << s_aTextures [1] -> getID () << std::endl;
glTexCoord2f (0.0f, 0.0f); glVertex3f ( 1.0f, -1.0f, -1.0f);
glTexCoord2f (0.0f, 1.0f); glVertex3f ( 1.0f, 1.0f, -1.0f);
glTexCoord2f (1.0f, 1.0f); glVertex3f (-1.0f, 1.0f, -1.0f);
glTexCoord2f (1.0f, 0.0f); glVertex3f (-1.0f, -1.0f, -1.0f);

// left

s_aTextures [2] -> setActive ();
glTexCoord2f (0.0f, 0.0f); glVertex3f (-1.0f, -1.0f, -1.0f);
glTexCoord2f (0.0f, 1.0f); glVertex3f (-1.0f, 1.0f, -1.0f);
glTexCoord2f (1.0f, 1.0f); glVertex3f (-1.0f, 1.0f, 1.0f);
glTexCoord2f (1.0f, 0.0f); glVertex3f (-1.0f, -1.0f, 1.0f);

// right

s_aTextures [3] -> setActive ();
glTexCoord2f (0.0f, 0.0f); glVertex3f ( 1.0f, -1.0f, 1.0f);
glTexCoord2f (0.0f, 1.0f); glVertex3f ( 1.0f, 1.0f, 1.0f);
glTexCoord2f (1.0f, 1.0f); glVertex3f ( 1.0f, 1.0f, -1.0f);
glTexCoord2f (1.0f, 0.0f); glVertex3f ( 1.0f, -1.0f, -1.0f);

// top

s_aTextures [4] -> setActive ();
glTexCoord2f (0.0f, 0.0f); glVertex3f (-1.0f, 1.0f, 1.0f);
glTexCoord2f (0.0f, 1.0f); glVertex3f (-1.0f, 1.0f, -1.0f);
glTexCoord2f (1.0f, 1.0f); glVertex3f ( 1.0f, 1.0f, -1.0f);
glTexCoord2f (1.0f, 0.0f); glVertex3f ( 1.0f, 1.0f, 1.0f);

// bottom

s_aTextures [5] -> setActive ();
glTexCoord2f (0.0f, 0.0f); glVertex3f ( 1.0f, -1.0f, 1.0f);
glTexCoord2f (0.0f, 1.0f); glVertex3f ( 1.0f, -1.0f, -1.0f);
glTexCoord2f (1.0f, 1.0f); glVertex3f (-1.0f, -1.0f, -1.0f);
glTexCoord2f (1.0f, 0.0f); glVertex3f (-1.0f, -1.0f, 1.0f);

glEnd ();
glDisable (GL_TEXTURE_2D);
}

Share this post


Link to post
Share on other sites
Have you tried replacing your setActive() call with:

glBindTexture (GL_TEXTURE_2D, s_aTextures [0] -> getID () );

Changing the 0 accordingly obviously.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!