![]() |
| | #1 |
| Absent Minded Programmer Join Date: May 2005
Posts: 933
| Loading a bitmap (Without using glaux) Code: LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
AUX_RGBImageRec *LoadBMP(const char *Filename) // Loads A Bitmap Image
{
FILE *File=NULL; // File Handle
if (!Filename) // Make Sure A Filename Was Given
{
return NULL; // If Not Return NULL
}
File=fopen(Filename,"r"); // Check To See If The File Exists
if (File) // Does The File Exist?
{
fclose(File); // Close The Handle
return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer
}
return NULL; // If Load Failed Return NULL
}
GLuint LoadGLTexture( const char *filename ) // Load Bitmaps And Convert To Textures
{
AUX_RGBImageRec *pImage; // Create Storage Space For The Texture
GLuint texture = 0; // Texture ID
pImage = LoadBMP( filename ); // Loads The Bitmap Specified By filename
// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
if ( pImage != NULL && pImage->data != NULL ) // If Texture Image Exists
{
glGenTextures(1, &texture); // Create The Texture
// Typical Texture Generation Using Data From The Bitmap
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, 3, pImage->sizeX, pImage->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, pImage->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
free(pImage->data); // Free The Texture Image Memory
free(pImage); // Free The Image Structure
}
return texture; // Return The Status
}
Something like Code: class BMPTexture
{
// storage structs
// Loading Code
};
Code: class MS3DModel
{
public:
MS3DModel();
virtual ~MS3DModel();
struct Vertex
{
char BoneID;
float Location[3];
};
int NumVertices;
Vertex *Vertices;
struct Triangle
{
float VertexNormals[3][3];
float Textures1[3], Textures2[3];
int VertexIndices[3];
};
int NumTriangles;
Triangle *Triangles;
struct Mesh
{
int MaterialIndex;
int NumTriangles;
int *TriangleIndices;
};
int NumMeshes;
Mesh *Meshes;
struct Material
{
float Ambient[4], Diffuse[4], Specular[4], Emissive[4];
float Shininess;
GLuint Texture;
char *TextureFilename;
};
int NumMaterials;
Material *Materials;
bool Load( const std::string & name );
void ReloadTextures();
void Draw();
};
Code: template< typename T_ >
class Resource_Manager
{
public:
typedef T_ value_type; // std library convention
typedef boost::shared_ptr<T_> Resource_Ptr;
typedef boost::weak_ptr<T_> Resource_Observer;
typedef std::map< std::string, Resource_Ptr > Resource_Map;
Resource_Manager<T_>() {};
~Resource_Manager<T_>() {};
Resource_Observer Request_Resource(const std::string & name)
{
Resource_Map::iterator it = mResources.find(name);
if (it == mResources.end())
{
Resource_Ptr Raw_Resource(new T_);
Raw_Resource->Load(name);
mResources.insert(std::make_pair(name, Raw_Resource));
Resource_Observer Resource(Raw_Resource);
return Resource;
}
else
{
return Resource_Observer(it->second);
}
}
void Request_Resource_Removal(const std::string & name)
{
Resource_Map::iterator it = mResources.find(name);
if (it != mResources.end())
{
mResources.erase(it);
}
}
private:
Resource_Map mResources;
};
Looking at the loading code more closely, LoadBMP actually returns a pointer to the actual bitmap, while the GLLoadTexture func creates the texID.. The reason I want to use my manager to do all this stuff is, not to sound boastful, basically that my resource manager can do a cleaner job than the auxDIBImageLoad function. I don't really have to worry about deleting stuff with my resource manager, it is a nice way to do things IMO.. I guess my dilemma is this.. My resource manager handles pointers, it doesn't handle ID's, thus I can't mix ID creation in with my texture manager, unless maybe I'm returning an observer with a tex ID in it..... Ah yes, that's it. If I mirror the MS3D setup I can easily add an ID in the info structs and then access the ID of the texture object with methods in that class.. So I'm guessing when I get down to it, it looks like this: Resource_Manager<BMPTexture> Textures; Textures.Request_Resource("texture name here"); Then I can access the ID via the return value of the request resource method, which is a resource observer.. Okay, is this making sense to you guys? Am I in rightful reason to want to avoid the auxDIBImageLoad function? Is what I'm proposing making sense to you guys? Thanks. EDIT: Really I just need to know how to load a bitmap without using auxDIBImageLoad..
__________________ Sometimes I forget what I am doing when I enter a room, actually, quite often. |
| Shamino is offline | |
| | #2 |
| Absent Minded Programmer Join Date: May 2005
Posts: 933
| So far this is what I've come up with.. Header Code: #ifndef BITMAP_H
#define BITMAP_H
#include <windows.h> // Windows header file.
#include <stdio.h> // Standard input/output.
#include <gl\gl.h>
#define BITMAP_ID 0x4D42 // The universal bitmap ID
class Bitmap
{
public:
Bitmap();
~Bitmap();
bool Load(const char *filename); // Load a .bmp image file.
void FreeImage(); // Delete a image.
void Transparent(int* g_keyColor);
unsigned int ID; // Texture ID.
int imageWidth; // Width of a texture.
int imageHeight; // Height of a texture.
unsigned char *image; // Texture image.
unsigned char *TRANimage;
};
#endif
Code: #include "Bitmap.h"
Bitmap::Bitmap()
{
// Give everything default values.
image = 0;
TRANimage = 0;
imageWidth = 0;
imageHeight = 0;
}
Bitmap::~Bitmap()
{
FreeImage();
}
bool Bitmap::Load(const char *file)
{
FILE *pFile = 0;
// These will hold the bitmap header and file information.
BITMAPINFOHEADER bitmapInfoHeader;
BITMAPFILEHEADER header;
// This will be used to swap the image colors from BGR to RGB.
unsigned char textureColors = 0;
// Open the file and make sure no errors.
pFile = fopen(file, "rb");
if(pFile == 0) return false;
// Read in the bitmap header info into the BITMAPFILEHEADER variable.
fread(&header, sizeof(BITMAPFILEHEADER), 1, pFile);
// Make sure this is a real bitmap by checking the ID.
if(header.bfType != BITMAP_ID)
{
fclose(pFile);
return false;
}
// Read in the second header info into the BITMAPINFOHEADER variable.
fread(&bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);
// Save the width and height.
imageWidth = bitmapInfoHeader.biWidth;
imageHeight = bitmapInfoHeader.biHeight;
// Make sure we read a size out of it.
if(bitmapInfoHeader.biSizeImage == 0)
bitmapInfoHeader.biSizeImage = bitmapInfoHeader.biWidth *
bitmapInfoHeader.biHeight * 3;
// Place the pointer in front of where the image data starts.
fseek(pFile, header.bfOffBits, SEEK_SET);
// Dynamically create enough memory for the image.
image = new unsigned char[bitmapInfoHeader.biSizeImage];
// Error checking. Make sure the memory was allocated.
if(!image)
{
delete[] image;
fclose(pFile);
return false;
}
// Read in the image.
fread(image, 1, bitmapInfoHeader.biSizeImage, pFile);
// Bitmaps are saved in BGR format so we will make the image RGB by...
for(int index = 0; index < (int)bitmapInfoHeader.biSizeImage; index+=3)
{
textureColors = image[index];
image[index] = image[index + 2];
image[index + 2] = textureColors;
}
// Close the file and return the image.
fclose(pFile);
return true;
}
void Bitmap::Transparent(int* g_keyColor)
{
int imageSize_RGB = imageWidth * imageHeight * 3;
int imageSize_RGBA = imageWidth * imageHeight * 4;
//allocate buffer for a RGBA image
TRANimage = new unsigned char[imageSize_RGBA];
// Loop through the original RGB image buffer and copy it over to the
// new RGBA image buffer setting each pixel that matches the key color
// transparent.
int i, j;
for(i = 0, j = 0; i < imageSize_RGB; i += 3, j += 4 )
{
// Does the current pixel match the selected color key?
if( image[i] == g_keyColor[0] &&
image[i+1] == g_keyColor[1] &&
image[i+2] == g_keyColor[2] )
{
TRANimage[j+3] = 0; // If so, set alpha to fully transparent.
}
else
{
TRANimage[j+3] = 255; // If not, set alpha to fully opaque.
}
TRANimage[j] = image[i];
TRANimage[j+1] = image[i+1];
TRANimage[j+2] = image[i+2];
}
}
void Bitmap::FreeImage()
{
// When the application is done delete all memory.
if(image)
{
delete[] image;
image = NULL;
}
if(TRANimage)
{
delete[] TRANimage;
TRANimage = NULL;
}
}
So, with my resource manager, I'll be able to pass a texture filename, and it will return a pointer, which I can use to get the ID.. No repeating textures, no dangling memory anywhere.. Hurrah for my resource manager!
__________________ Sometimes I forget what I am doing when I enter a room, actually, quite often. |
| Shamino is offline | |
| | #3 |
| Crazy Fool Join Date: Jan 2003 Location: Canada
Posts: 2,596
| >>EDIT: Really I just need to know how to load a bitmap without using auxDIBImageLoad.. http://gpwiki.org/index.php/LoadBMPCpp
__________________ jeff.bagu.org - Terrain rendering and other random stuff |
| Perspective is offline | |
| | #4 |
| Absent Minded Programmer Join Date: May 2005
Posts: 933
| Hmm, that might work... I'd need to modify the main object to store a GL tex id though, shouldn't be difficult..
__________________ Sometimes I forget what I am doing when I enter a room, actually, quite often. |
| Shamino is offline | |
| | #5 |
| Registered User Join Date: Mar 2006
Posts: 3
| Sometimes BMPs will have spacefillers of a couple of byte at the ends of each row of pixel data. I don't see any compensation for that in the wiki code, it may not be required though since it's reading the BMP data differently than I did. When I wrote my BMP loader I read it in by bytes (it was a while ago...) and I had to calculate how much blank space was at the end of each line to skip over it. If the images are messing up (diagonally skewed) you'll need to skip over these non-data bytes. In one of the header variables it says how long the image data is. You also have height and width in pixels. If image data length != height * width, you read each rox of pixels to the width of the image, then skip a number of bytes equal to [(data length) - (height * width)]/width I wish I had my code here, unfortunately it's on a different computer. The wiki code looks much nicer though anyways ![]() ~Mith |
| MithTS is offline | |
| | #6 |
| Absent Minded Programmer Join Date: May 2005
Posts: 933
| Thanks for the heads up Mith
__________________ Sometimes I forget what I am doing when I enter a room, actually, quite often. |
| Shamino is offline | |
| | #7 |
| Super Moderator Join Date: Aug 2001
Posts: 7,817
| Each row in a BMP is zero-padded to the nearest 4 byte boundary. BMPs are stored in exact reverse color order as the hardware expects. BMPs are stored using bottom right corner as starting place or 0.
__________________ If you aim at everything you will hit something but you won't know what it is. |
| Bubba is offline | |
| | #8 |
| The Right Honourable Join Date: Mar 2004 Location: Where circles begin.
Posts: 1,068
| "BMPs are stored in exact reverse color order as the hardware expects." Naturally.
__________________ Memorial University of Newfoundland Computer Science Mac and OpenGL evangelist. |
| psychopath is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Loading bitmap file into a HBITMAP | wind_addict | Windows Programming | 9 | 11-17-2007 10:42 AM |
| OpenGL -- Bitmaps | HQSneaker | Game Programming | 14 | 09-06-2004 04:04 PM |
| Loading a Bitmap resource for OpenGL Texture[x] | the dead tree | Game Programming | 4 | 08-26-2004 01:12 PM |
| Loading bitmap in dll | Mithoric | Windows Programming | 2 | 12-22-2003 01:53 PM |
| No one can seem to help me, loading bitmap | Shadow12345 | C++ Programming | 7 | 12-28-2002 01:22 PM |