How to load a bmp on GLUT to use it as a texture?

48,147

Solution 1

Look my simple c implementation function to load texture.

GLuint LoadTexture( const char * filename )
{
  GLuint texture;
  int width, height;
  unsigned char * data;

  FILE * file;
  file = fopen( filename, "rb" );

  if ( file == NULL ) return 0;
  width = 1024;
  height = 512;
  data = (unsigned char *)malloc( width * height * 3 );
  //int size = fseek(file,);
  fread( data, width * height * 3, 1, file );
  fclose( file );

  for(int i = 0; i < width * height ; ++i)
  {
    int index = i*3;
    unsigned char B,R;
    B = data[index];
    R = data[index+2];

    data[index] = R;
    data[index+2] = B;
  }

  glGenTextures( 1, &texture );
  glBindTexture( GL_TEXTURE_2D, 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_REPEAT );
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT );
  gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height,GL_RGB, GL_UNSIGNED_BYTE, data );
  free( data );

  return texture;
}

Above function returns the texture data. Store the texture data in variable

GLuint texture;
texture= LoadTexture( "your_image_name.bmp" );

Now you can bind the texture using glBindTexture

glBindTexture (GL_TEXTURE_2D, texture);

Solution 2

You can use library GLAUX and SOIL(Simple OpenGL Image Library) . There are also other image libriries for OpenGL.

Solution 3

Checkout my the TextureLoader (TextureLoader.h + TextureLoader.cpp) from OpenGL_3_2_Utils:

https://github.com/mortennobel/OpenGL_3_2_Utils

The two files does not depend on any other files and should also work seamless on any version of OpenGL (and any platform). Example usage can be found in the file comment.

Solution 4

How to load a bmp on GLUT to use it as a texture?

Another very simple solution would be to use STB library, which can be found at GitHub - nothings/stb.

All what is needed is one source file, the header file "stb_image.h". It doesn't require to link any library file or to compile any additional source file.

Include the header file and enable image reading by the setting the preprocessor definition STB_IMAGE IMPLEMENTATION:

#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

The image file can be read by the function stbi_load:

const char *filename = .....; // path and filename
int         req_channels = 3; // 3 color channels of BMP-file   

int width = 0, height = 0, channels = 0;
stbi_uc *image = stbi_load( filename, &width, &height, &channels, 3 ); 

When the image is loaded to a texture object, then GL_UNPACK_ALIGNMENT has to be set to 1.
By default GL_UNPACK_ALIGNMENT is 4, so each line of an image is assumed to be aligned to 4 bytes. The pixels of a BMP-file in common have a size of 3 bytes and are tightly packed, this would cause a misalignment.
After loading the image, the memory can be freed by stbi_image_free:

GLuint texture_obj = 0;
if ( image != nullptr )
{
    glGenTextures(1, &texture_obj);
    glBindTexture(GL_TEXTURE_2D, texture_obj);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // default

    stbi_image_free( image );
}

Solution 5

improved version

GLuint LoadTexture(GLuint tex, const char * filename, int width, int height)
{
//bmp 24 bit
unsigned char * data;
unsigned char R,G,B;
FILE * file;

//open .bmp
file = fopen(filename, "rb");

if(file == NULL)return 0;
//get memory for data
data =(unsigned char *)malloc(width * height * 3);
//data skip offset 
fseek(file,128,0);
//read file to data
fread(data, width * height * 3, 1, file);
//close file
fclose(file);

//transpose R,G,B values
int index;
for(int i = 0; i < width * height ; ++i)
    {
    index = i*3;
    B = data[index]; G = data[index+1]; R = data[index+2];
    data[index] = R; data[index+1] = G; data[index+2] = B;
    }

//create a texture
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGB, GL_UNSIGNED_BYTE, data);

//texture filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

//free memory
free(data);
return 0;
}


void init(void)
{
//texture loading, bmp 24 bit
LoadTexture(1, "01.bmp", 316, 316);
LoadTexture(2, "02.bmp", 316, 316);
LoadTexture(3, "05.bmp", 316, 316);
LoadTexture(4, "03.bmp", 316, 316);
LoadTexture(5, "06.bmp", 316, 316);
LoadTexture(6, "04.bmp", 316, 316);

. . . . . . . . . . . .

enter image description here

Linux

gcc cube.c -o cube -lglut -lGL -lGLU

Windows

tcc cube.c -o cube.exe -LC:\tcc\lib -lopengl32 -lglu32 -lglut32 -Wl,-subsystem=windows

Share:
48,147

Related videos on Youtube

Patricio Jerí
Author by

Patricio Jerí

Updated on July 05, 2022

Comments

  • Patricio Jerí
    Patricio Jerí almost 2 years

    I've been searching all around for a simple solution to add sprites to my OpenGl GLUT simple moon lander game in c++ and it appears I must use bmp's since they're easiest to load and use them as textures on a rectangle.

    How exactly can I load the bmp's as textures though?

  • Patricio Jerí
    Patricio Jerí over 11 years
    How do I add the missing glew.h file? Posted a question about this here stackoverflow.com/questions/12518757/…
  • Nicol Bolas
    Nicol Bolas over 11 years
    SO has a spam policy that requires disclosure when you mention tools or applications you develop. You have to actually say they're yours.
  • Mortennobel
    Mortennobel over 11 years
    @NicolBolas No problem. I didn't know that. I updated the question to clarify it.
  • Mortennobel
    Mortennobel over 11 years
    @PatricioJerí Actually you don't need to glew.h file. I have removed the dependency from the TextureLoader.h file. Thanks for pointing that out!
  • Patricio Jerí
    Patricio Jerí over 11 years
    @Mortennobel You're welcome :P, however, this doesn't seem to be compatible with my processors architecture or something of the sort. After a lot of debugging there was nothing else I could do. Thank you though :)
  • Admin
    Admin almost 10 years
    although you can throw an extra fread(data, 54, 1, file) to strip the typical BMP buffer...
  • Tobias Reich
    Tobias Reich over 9 years
    Thanks for that. I had to do this without using additional libraries. So this seems to work. Thanks! :)
  • Crew HaXor
    Crew HaXor over 9 years
    I used your code to implement an image in my program .it loads the bmp file but did not display any thing on screen.
  • ManuelJE
    ManuelJE almost 4 years
    Hey, but you're calling glBindTexture() twice with the same parameters! First inside the function and then after the function returns in the call example...
  • maxterthrowaway
    maxterthrowaway over 2 years
    I am having the same issue as the other user where the BMP files load but do not display anything on the screen. It's just a black box where the texture would've been
  • Severin Turin
    Severin Turin over 2 years