Jump to content

  • Log In with Google      Sign In   
  • Create Account


Creating texture from BMP file


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 nyl2000   Members   -  Reputation: 129

Like
0Likes
Like

Posted 14 March 2013 - 08:22 AM

I am currently trying to draw a plane texture in openGL from a loaded BMP file. Only I don't know the exact codes to do this. I understand that getBMPData(), glBindTexture(), and glTexImage() are some of the functions I need, but I could use an example to understand how to use them.



Sponsor:

#2 EVIL_ENT   Members   -  Reputation: 212

Like
0Likes
Like

Posted 14 March 2013 - 03:29 PM

// To create our window
#include <GL/glut.h>

#ifndef GL_BGRA
#define GL_BGRA 0x80E1
#endif

// For BITMAPFILEHEADER and BITMAPINFOHEADER
#include <windows.h>

#include <stdio.h>

GLuint test_texture_id;

void display(){
    glClear(GL_COLOR_BUFFER_BIT);

    // One vertex is (2 + 2)*4 bytes (2 GLfloats for position, 2 GLfloats for texture coordinates, 4 bytes per GLfloat)
    const int SIZE_OF_VERTEX = (2 + 2)*sizeof(GLfloat);

    GLfloat data[] = {// 2 texture coordinates followed by 2 vertex coordinates in counterclockwise order
        0, 0, -1, -1,// Bottomleft
        1, 0, +1, -1,// Bottomright
        1, 1, +1, +1,// Topright
        0, 1, -1, +1,// Topleft
    };

    // Use this texture
    glBindTexture(GL_TEXTURE_2D, test_texture_id);



    // Tell OpenGL where our vertex data begins and how big each vertex is
    glTexCoordPointer(2, GL_FLOAT, SIZE_OF_VERTEX, data+0);// Texture data begins at index 0
    glVertexPointer  (2, GL_FLOAT, SIZE_OF_VERTEX, data+2);// Vertex  data begins at index 2
    // Draw data
    glDrawArrays(GL_QUADS, 0, 4);

    // We can also draw like this instead (slower but probably more familiar)
/*
    glBegin(GL_QUADS);
    int i;
    for (i=0; i<16; i+=4){
        glTexCoord2f(data[i+0], data[i+1]);
        glVertex2f(data[i+2], data[i+3]);
    }
    glEnd();
*/
    glutSwapBuffers();
}

void reshape(int w, int h){
    glViewport(0, 0, w, h);
}

int main(int argc, char *argv[]){
    glutInit(&argc, argv);
    glutCreateWindow("");

    glutDisplayFunc(display);
    glutReshapeFunc(reshape);

    // Make us able to draw with single function calls (faster)
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    // Make OpenGL draw texture on our triangles/quads/etc
    glEnable(GL_TEXTURE_2D);

    // Enable alpha so we can see through transparent images
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // Generate a texture id for our texture so we can find it again later
    glGenTextures(1, &test_texture_id);
    // Use this texture id
    glBindTexture(GL_TEXTURE_2D, test_texture_id);
    // Associate this texture id with some texture-specific data
    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_LINEAR);

    /// THIS BITMAP _MUST_ BE 32 BIT BMP!!! (e.g. gimp can export these)

    FILE *fp = fopen("test.bmp", "rb");

    // Load bitmap header
    BITMAPINFOHEADER bmih;
    BITMAPFILEHEADER bmfh;
    fread(&bmfh, 1, sizeof(bmfh), fp);
    fread(&bmih, 1, sizeof(bmih), fp);
    fseek(fp, bmfh.bfOffBits, SEEK_SET);
    // Width of image should be 2^n (2, 4, 8, 16, 32, 64, ...)
    int w = bmih.biWidth;
    int h = bmih.biHeight;
    // Number of bytes (RGBA = 4*1 byte, one byte per color)
    int n = w*h*4;
    void *data = malloc(n);
    fread(data, 1, n, fp);
    // Data loaded from disc to RAM, no need to keep this file open
    fclose(fp);

    // Upload data to GPU (we use GL_BGRA format because bmp colors are messed up)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);

    // Data is in GPU memory, we can delete it from RAM now
    free(data);

    glutMainLoop();

    return 0;
}

I don't recommend this way of loading images or even BMP images, but for testing it is good enough I guess.

I usually use PNG and some library to load it, but the choice mostly depends on what constraints you have.

 

Note that this is very old OpenGL (which is easier to learn imho but slower than new OpenGL and less versatile).

This is newer OpenGL: https://github.com/progschj/OpenGL-Examples

 

For simplicity I used 32-bit bmps because they are easier to load since they don't have weird padding bytes every row of pixels (the alpha channel is nice, too).

 

If you don't have glut and are using Code::Blocks you can get something better here: http://www.transmissionzero.co.uk/software/freeglut-devel/

Just copy the all the include files into your MinGW include folder and the libfreeglut.a into the MinGW lib folder, add -lfreeglut under linkers somewhere and you are good to go (there are other similar ways to do this).

Attached Files

  • Attached File  test.bmp   1.12KB   45 downloads


#3 EddieV223   Members   -  Reputation: 1404

Like
0Likes
Like

Posted 14 March 2013 - 05:34 PM

freeimage is a great library, it uses libpng as well as the other libs for opening image files.  It however makes it much easier to do so.  glfw has a tga loading function.

 

If you really want to learn to load a bmp by hand ( it's a good learning experience ) then you need to find the right information.  Every image has a file header, its the first part of the file's structure that hold the information that you need to know to read and file.  Such as width and height, bits per pixel, things like this.  Once you have that its pretty easy

 

You just read the header into a struct, then your data should be next in the file, from the information in the header you should be able to figure out the total number of bytes in the data section.  Read this in as an array of chars ( or bytes ).  Then when you create your buffer do the following function call to send that data to openGL.

 

//mWidth is the image width from the image header

//mHeight is the image height from the image header

// mpBytes is a pointer to the char array, its size should be (mWidth * mHeight * (bitsPerPixel / 8))  ( this is in bytes ).

 

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, mpBytes );

 

// You may need to change the GL_BGRA to whatever format your image is in.  In my case its R G B and A channels but in BGRA order.

 

There are other ways to send your image data to openGL such as mapping the buffer, but this way is easier.

 

If you want to see an example of bmp loading look at this tutorial

http://www.opengl-tutorial.org


Edited by EddieV223, 14 March 2013 - 05:39 PM.

If this post or signature was helpful and/or constructive please give rep.

 

// C++ Video tutorials

http://www.youtube.com/watch?v=Wo60USYV9Ik

 

// Easy to learn 2D Game Library c++

SFML2.1 Download http://www.sfml-dev.org/download.php

SFML2.1 Tutorials http://www.sfml-dev.org/tutorials/2.1/

 

// SFML 2 book

http://www.amazon.com/gp/product/1849696845/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=1849696845&linkCode=as2&tag=gamer2creator-20

 





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS