0

I made my own bitmap loader. There's a function that loads the data from the file. It is 24bit.

This is the file's hex data:

42 4d 46 00 00 00 00 00 00 00 36 00 00 00 28 00
00 00 02 00 00 00 02 00 00 00 01 00 18 00 00 00
00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 ff ff ff ff 00 00 ff 00
00 00 ff 00 00 00

This is my loader (also outputs info to a file):

void load_texture(std::string path)
{
    std::ifstream f;
    f.open(path, std::ios_base::binary);
    std::vector<unsigned char> store;
    char buf[255];
    while(!f.eof())
    {
        unsigned char g;
        f >> g;
        store.push_back(g);
    }
    f.close();

std::ofstream l("info.txt");
    int offset = store[0xA];
    int width = store[0x12];
    int height = store[0x16];
    int sizeraw = ((width*3)*height)+height-1*2;
    int a = store[(int)offset+1];
    int pad = 0;
    std::vector<BGR*> imageraw;
    std::vector<int*> image;
    for(int y = 0; y < height;y++)
    {
        for(int x = pad; x < pad + (width*3); x+=3)
        {
            imageraw.push_back(new BGR(store[offset +x], store[offset +x+1], store[offset +x+2]));
        }
        pad += (width*3)+2;
    }
    for(int i = 0; i < imageraw.size(); i++)
    {
        l << "---------------------------------\n";
        image.push_back(new int(imageraw[i]->B));
        image.push_back(new int(imageraw[i]->G));
        image.push_back(new int(imageraw[i]->R));
        l << "B : "; l << imageraw[i]->B; l << " \n";
        l << "G : "; l << imageraw[i]->G; l << " \n";
        l << "R : "; l << imageraw[i]->R; l << " \n";
    }
    glEnable(GL_TEXTURE_2D);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, image.data());

l.close();

}

And this is the BGR structure:

struct BGR
{
    int B;
    int G;
    int R;

    BGR(int a, int b, int c): B(a), G(b), R(c) {};
};

I don't know why, but OpenGL displays the image in the wrong colors. I also have to point out that I'm a beginner at working with hexadecimal data in files. Also, the output to the file (info.txt) comes out correct.

Why does OpenGL display the wrong colors?

Another thing, what I wanna give to OGL is the integer values of BGR, like the ones in info.txt. No hex nor bin. EDIT:

This is the file result:

---------------------------------
B : 0 
G : 0 
R : 255 
---------------------------------
B : 255 
G : 255 
R : 255 
---------------------------------
B : 255 
G : 0 
R : 0 
---------------------------------
B : 0 
G : 255 
R : 0 
  • 1
    `while(!f.eof())` no no no no no – Lightness Races in Orbit Mar 31 '14 at 23:04
  • @LightnessRacesinOrbit That's not the problem. I also tried while(f.good()). The problems seems to be more about OGL than the engine itself because the info.txt file has the correct information. – user3483035 Mar 31 '14 at 23:08
  • Regardless, it's wrong. You'll be adding an extra element to `store` each time, with an unspecified value. `while (f.good())` has the same problem. Which book are you using? – Lightness Races in Orbit Mar 31 '14 at 23:12
  • 1
    Binary files do not store hexadecimal values. That's just one representation. – David Heffernan Mar 31 '14 at 23:13
  • @LightnessRacesinOrbit I am not using a book. When I need something I adventure myself in this weird jungle of information (also called Internet :) ). I'll edit the question with the file result. – user3483035 Mar 31 '14 at 23:14
  • The internet is littered with false information on C++, due to its age and popularity. You should learn from [a good, peer-reviewed book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). You cannot properly learn something as complex as C++ by Googling. Perform real research! – Lightness Races in Orbit Mar 31 '14 at 23:21
  • @LightnessRacesinOrbit It's not like I am learning the C++ language. It's just the hexadecimal part because I'm familiar with the rest. – user3483035 Mar 31 '14 at 23:25
  • Concerning the eof part, @LightnessRacesinOrbit is probably talking about [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/q/5605125) which you should certainly read. – AliciaBytes Mar 31 '14 at 23:27
  • @RaphaelMiedl It's an interesting question, but after some testings it does not change anything. eof is working fine here. What mostly concerns me is the type of data OGL gets when I give him the pixel array. Basically it loads fine, stores fine, but then Opengl shows incorrect textures. I still don't get this. – user3483035 Mar 31 '14 at 23:30
  • I never said it resolves _this_ issue. Still, it's disappointing you don't seem to care about such a flaw in your code. :( Anyway, to make a better question you should provide an example of what output you _did_ expect. You could then abstract away OpenGL. It's likely you can abstract away all the BMP shenanigans, too, as the origins of your data file format aren't particularly relevant. http://sscce.org – Lightness Races in Orbit Apr 01 '14 at 00:17
  • 1
    @LightnessRacesinOrbit The file output I got was the one I wished but Opengl isn't display the correct colors. Please help. I really need this thing working. – user3483035 Apr 01 '14 at 00:32

2 Answers2

0

GL_UNPACK_ALIGNMENT assume that each row of your image is multiple of 4, if not, you'll get pixel miss alignment.

glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

Your pixel structure being 3 bytes, changing unpack alignment to 1 will ensure no shift between lines.

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

You may also shift byte(s) yourself (at bmp creation) between each line to have their byte count multiple of 4.

j-p
  • 1,622
  • 10
  • 18
0

Your are sending totally wrong data to the GL:

std::vector<int*> image;

Here, you are using a vector of pointers to integers and you add 3 pointerts to newly allocated images per pixel. This is nothing the GL will be able to work with.(And as a side note: you are also leaking a hell lots of memory here).

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, image.data())

Now you are telling the GL that it will find an image of width times height pixels containing of BGR image data, with each component beeing an GL_UNSIGNED_BYTE, so of type GLubyte (or, in any partical case unsigned char) beginning at adress image.data(). So you don't need ints, and you cartainly don't need int* pointers.

Your std::vector<BGR*> imageraw; and std::vector<int*> image; data structures are in fact completele useless, you could directly use the relevant part of your store vector, which will contain the data in the correct format already (assui=ming non-compressed standard BMP files, but the rest of your code assumes the same).

derhass
  • 43,833
  • 2
  • 57
  • 78
  • store is storing the whole file data including the header. It does not simply store the bitmap data. So how can I "give" OGL the bitmap array in the store? – user3483035 Apr 01 '14 at 19:29
  • By using the correct pointer. The bitmap data will start somewhere after the header. – derhass Apr 01 '14 at 20:00