Rhys Gale
Rhys Gale

Reputation: 29

C++ OpenGL Texture not loading

void OGLRectangle::LoadTexture(const char* filename)
{
unsigned int texture;
int width, height;
BYTE * data;
FILE * file;

file = fopen(filename, "rb");

width = 1920;
height = 1080;
data = new BYTE[height * width * 3];

fread(data, width * height * 3, 1, file);
fclose(file);

glGenTextures(1.0, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
tex = texture;
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glTexImage2D(GL_TEXTURE_2D, 0, 2, width, height,0, GL_RGB, GL_UNSIGNED_BYTE, data);

delete [] data;

}

I have this code to render in an image, the method is called with: LoadTexture("C:\\Users\Rhys\Documents\Hills.bmp"); The file exists.

Then I'm trying to render it to the openGL window using;

    glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
glBegin(GL_QUADS);
glTexCoord2d(0.0, 0.0); glVertex2d(0.0, 0.0);
glTexCoord2d(1.0, 0.0); glVertex2d(100.0, 0.0);
glTexCoord2d(1.0, 1.0); glVertex2d(100.0, 100.0);
glTexCoord2d(0.0, 1.0); glVertex2d(0.0, 100.0);
glEnd();
glDisable(GL_TEXTURE_2D);

However, all I'm getting on screen is a darkish blue box, with no texture rendered in it. I have searched for tutorials on how to do this, even asked my lecturer and I still cannot seem to find out why its not working. Any help will be greatly appreciated.

Upvotes: 2

Views: 1112

Answers (2)

Reto Koradi
Reto Koradi

Reputation: 54652

You're setting the attribute to sample with mipmaps:

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);

You should only set that if your textures actually has mipmaps. To generate mipmaps, you can call:

glGenerateMipmap(GL_TEXTURE_2D);

after the glTexImage2D() call. Or you can simply set the sampler attribute to not use mipmaps:

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

As has already been pointed out: If your image file is indeed a BMP, and not just a raw image file, your image loading code will also need work.

Upvotes: 1

Mykola
Mykola

Reputation: 3373

The .bmp files loading must be little different

This code simply loads bmp file to memory m_pcbData without compression and indexed color support.

bool CBMPImage::LoadFromFile(const CString& FileName)
{
    BITMAPINFOHEADER BitmapInfo;
    ZeroMemory(&BitmapInfo, sizeof(BITMAPINFOHEADER));

    BITMAPFILEHEADER BitmapFile;
    ZeroMemory(&BitmapFile, sizeof(BITMAPFILEHEADER));

    std::ifstream FileStream(FileName, std::ios::binary | std::ios::in);

    if (!FileStream.good())
        return false;

    // Read bitmap file info
    FileStream.read(reinterpret_cast<char*>(&BitmapFile), sizeof(BITMAPFILEHEADER));
    // Read bitmap info
    FileStream.read(reinterpret_cast<char*>(&BitmapInfo), sizeof(BITMAPINFOHEADER));

    // Proper bitmap file supports only 1 plane
    if (BitmapInfo.biPlanes != 1)
        return false;

    m_cbAlphaBits = 0;
    m_cbRedBits = 0;
    m_cbGreenBits = 0;
    m_cbBlueBits = 0;

    // Retrives bits per pixel info
    m_cbBitsPerPel = (BMPbyte)BitmapInfo.biBitCount;

    // Width and height of image
    m_nWidth = BitmapInfo.biWidth;
    m_nHeight = BitmapInfo.biHeight;

    // Compute bitmap file size
    m_nSize = 4 * ((m_nWidth * m_cbBitsPerPel + 31) / 32) * m_nHeight;

    // Less important info
    m_nPixelWidthPerMeter = BitmapInfo.biXPelsPerMeter;
    m_nPixelHeightPerMeter = BitmapInfo.biYPelsPerMeter;

    // Indexes info not important in our case
    m_nClrCount = BitmapInfo.biClrUsed;
    m_nClrImportant = BitmapInfo.biClrImportant;

    // COMPRESSION MUST BE BI_RGB
    m_Compression = (BMPCompression)BitmapInfo.biCompression;

    delete [] m_pcbData;
    m_pcbData = NULL;

    // Allocate proper data size 
    m_pcbData = new BMPbyte[m_nSize];

    // Read actual image data, considering offset of file header
    FileStream.seekg(BitmapFile.bfOffBits);
    FileStream.read(reinterpret_cast<char*>(m_pcbData), m_nSize);

    FileStream.close();

    return true;
}

than load bmp texture data to OpenGL

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Image.GetWidth(), Image.GetHeight(), 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid*)Image.GetImageData());

GL_BGR_EXT is important because bmp stores image data in reverse byte order.

Secondly you must specify your material color as white because of usage that texture environment GL_TEXTURE_ENV_MODE, GL_MODULATE

And as mentioned @Reto Koradi, you must specify to generate mipmaps before texture image loading using one of these function calls.

glGenerateMipmap(GL_TEXTURE_2D);

or

glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);

Plus as you used not power of two textures (width = 1920; height = 1080;) it may not work.

Upvotes: 2

Related Questions