mechacrash
Level 1
It's almost like I'm actually being productive!
|
|
« on: November 29, 2009, 03:44:38 PM » |
|
I am trying to load up a bitmap image in openGL but I have a problem. I looked at Nehe's tutorial number 33 on how to load up TGA formats and that all works perfectly but he used a glaux function to load bitmaps and I do not want to do this. I looked at the code for the TGA loading and thought I would be able to port it over to load bitmaps, I downloaded a free hex editor and found that the first two values were always B and M and then i searched for where the width and height was and they were at 0x12 and 0x16 but they weren't the byte values they were the word values at these locations. Now I don't know a thing about hex editing but how would I be able to get these values in C++. At the moment I use this: FILE *file; if (!filename){ return 0; } file=fopen(filename,"rb"); if (!file){ return 0; } if(fread(&_header, sizeof(_header),1, file)==0){ if(file){ fclose(file); return 0; } } This puts all the byte values into my array. How do I get it to do this with the word values instead.
|
|
|
Logged
|
|
|
|
LemonScented
|
|
« Reply #1 on: November 29, 2009, 03:58:34 PM » |
|
Rather than having an array of bytes to load the header into, you should probably just have a header structure written into your code, which matches the structure of the actual file format. Googling for "BMP file format" seems to come up with some good stuff, and you should be able to find some pages which contain chunks of C/C++ code which define structures that you can just read into from the file and then get the values from. Does that make sense?
|
|
|
Logged
|
|
|
|
BlueSweatshirt
|
|
« Reply #2 on: November 29, 2009, 04:01:11 PM » |
|
I don't know if this applies, but I have some glaux replacement code for loading bitmaps, that you might be interested in. Header //---------------------------------------------------------------------------
class AUX_RGBImageRec { void convertBGRtoRGB(); public: byte *data; DWORD sizeX; DWORD sizeY; bool NoErrors; AUX_RGBImageRec(): NoErrors(false), data(NULL) {}; AUX_RGBImageRec(const char *FileName); ~AUX_RGBImageRec(); bool loadFile(const char *FileName); friend AUX_RGBImageRec *auxDIBImageLoad(const char *FileName); };
Source //-------------------------------------------------------------- #include <windows.h> // Header File For Windows - has structures for BMP format #include <stdio.h> // Header File For Standard Input/Output #include <stdlib.h> #include "BMP.h"
/*------------------------------------------------------------------ BMP Loader - a quick and dirty substitute for GLaux if you only use GLaux to load BMP files will load any format of a windows DIB BMP format graphics file Only works on a windows box Caution! memory for the data is allocated using 'new'. In the NeHe tutorials the memory is reclaimed using 'free'. For the small tutorials its not a big deal but not a good practice in larger projects (heap trashing not good). J.M. Doyle : 12 Jan 2003 ------------------------------------------------------------------*/
AUX_RGBImageRec *auxDIBImageLoad(const char *FileName) { return new AUX_RGBImageRec(FileName); }
void AUX_RGBImageRec::convertBGRtoRGB() { const DWORD BitmapLength = sizeX * sizeY * 3; byte Temp; // not quick but it works for(DWORD i=0; i< BitmapLength; i += 3) { Temp = data[i]; data[i] = data[i+2]; data[i+2] = Temp; } }
AUX_RGBImageRec::AUX_RGBImageRec(const char *FileName): data(NULL), NoErrors(false) { loadFile(FileName); }
AUX_RGBImageRec::~AUX_RGBImageRec() { if (data != NULL) delete data; data = NULL; }
bool AUX_RGBImageRec::loadFile(const char* Filename) { BITMAPINFO BMInfo; // need the current OpenGL device contexts in order to make use of windows DIB utilities const HDC gldc = wglGetCurrentDC(); // a handle for the current OpenGL Device Contexts // assume there are errors until file is loaded successfully into memory NoErrors = false; // release old data since this object could be used to load multiple Textures if(data != NULL) delete data; // windows needs this info to determine what header info we are looking for BMInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // Get windows to determine color bit depth in the file for us BMInfo.bmiHeader.biBitCount = 0; // Get windows to open and load the BMP file and handle the messy decompression if the file is compressed // assume perfect world and no errors in reading file, Ha Ha HANDLE DIBHandle = LoadImage(0,Filename, IMAGE_BITMAP, 0, 0,LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_LOADFROMFILE); // use windows to get header info of bitmap - assume no errors in header format
GetDIBits(gldc, (HBITMAP)DIBHandle, 0,0, NULL, &BMInfo, DIB_RGB_COLORS); sizeX = BMInfo.bmiHeader.biWidth; sizeY = BMInfo.bmiHeader.biHeight; // change color depth to 24 bits (3 bytes (BGR) / pixel) BMInfo.bmiHeader.biBitCount = 24; // don't want the data compressed BMInfo.bmiHeader.biCompression = BI_RGB; const DWORD BitmapLength = sizeX * sizeY * 3; // 3 bytes (BGR) per pixel (24bp) // allocate enough memory to hold the pixel data in client memory data = new byte[BitmapLength]; // Get windows to do the dirty work of converting the BMP into the format needed by OpenGL // if file is already 24 bit color then this is a waste of time but makes for short code // Get the actual Texel data from the BMP object if (GetDIBits(gldc, (HBITMAP)DIBHandle, 0, sizeY, data, &BMInfo, DIB_RGB_COLORS)) { NoErrors = true; convertBGRtoRGB(); // NOTE: BMP is in BGR format but OpenGL needs RGB unless you use GL_BGR_EXT }
DeleteObject(DIBHandle); // don't need the BMP Object anymore return NoErrors; }
( not claiming ownership, the author is clearly stated in the source comments )
|
|
|
Logged
|
|
|
|
Sos
|
|
« Reply #3 on: November 30, 2009, 05:08:01 AM » |
|
GLuint texture; // opengl texture pointer unsigned char *colors; // actual RGBA texture unsigned int width,height,bpp,c,datasize; FILE *f;
fopen(f,"probablyporn.tga","rb"); for (c=0;c<12;c++) fgetc(f);
width= fgetc(f)|(fgetc(f)<<8); height= fgetc(f)|(fgetc(f)<<8); bpp=fgetc(f); fgetc(f);
datasize=width*height*(bpp/8); colors=malloc(datasize*sizeof(unsigned char));
for(c=0;c<datasize) colors[c]=fgetc(f);
glGenTextures( 1, &texture ); glBindTexture( GL_TEXTURE_2D, texture ); // glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); // you might need it later. glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_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, bpp/8, width, height, (bpp==32 ? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, &colors); glEnable(GL_TEXTURE_2D);
free(colors); fclose(f);
and there, you are a happy texture owner. Enjoy
|
|
« Last Edit: November 30, 2009, 05:17:26 AM by Sos »
|
Logged
|
|
|
|
mechacrash
Level 1
It's almost like I'm actually being productive!
|
|
« Reply #4 on: November 30, 2009, 02:29:57 PM » |
|
I have a new question. I ended up getting a working bmp loader and it is all okay apart from a few pixels which are supposed to be on the right hand side of the image are wrapped around to the left side of the image and i dont understand why.
|
|
|
Logged
|
|
|
|
|
Sos
|
|
« Reply #6 on: December 01, 2009, 11:45:08 AM » |
|
He would get out-of-horizontal-sync-style-effect if he'd done that. I suggest getting rid of repeat wrapping. so replace this glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
with this glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP);
|
|
|
Logged
|
|
|
|
|