WARNING semi-large post follows.
As an exercise for myself, I wrote a class to load a .bmp image for use as a texture. Once I had it working, I went to NeHe''s tutorials to use it to load the textures. The first one I tried it on was number 10. It work great on this one. I then tried it on number 23 and started getting some weird error, not related to my code, but only happened when my code was in there. I then tried it on the first texture tutorial, number 6. The same weird error occured. Not a compilation error, but a runtime error.
Here''s the error:
Debug error!
Program:.....lesson6.exe
DAMGE: After Normal block (#23) at 0x007252c8
(Press retry to debug the application.
When I try to debug, it just brings me into an assembly listing that is not any of my code.
The funny thing is, when I try it in an OpenGL program of my own to load 3 textures, it works fine. It seems to be hit and miss. Anyone have any ideas?
Here is my bitmap.h file:
#ifndef _BITMAP_H
#define _BITMAP_H
//File: Bitmap.h
//Written by: Mark Bernard
//on GameDev.net: Captain Jester
//e-mail: mark.bernard@rogers.com
//Please feel free to use and abuse this code as much
//as you like. But, please give me some credit for
//starting you off on the right track.
//
//The file Bitmap.cpp goes along with this file
//
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
#include <windows.h>
const WORD BITMAP_MAGIC_NUMBER=19778;
class Bitmap {
public:
//variables
RGBQUAD *colours;
BYTE *pixelData;
bool loaded;
LONG width,height;
WORD bpp;
string error;
//methods
Bitmap(void);
Bitmap(char *);
~Bitmap();
bool loadBMP(char *);
private:
//variables
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
//methods
void reset(void);
};
#endif //_BITMAP_H
And my bitmap.cpp
//File: Bitmap.cpp
//Written by: Mark Bernard
//on GameDev.net: Captain Jester
//e-mail: mark.bernard@rogers.com
//Please feel free to use and abuse this code as much
//as you like. But, please give me some credit for
//starting you off on the right track.
//
//The file Bitmap.h goes along with this file
//
#include "Bitmap.h"
//basic constructor
Bitmap::Bitmap(){
reset();
}
//constructor loads the bitmap when it is created
Bitmap::Bitmap(char *file){
reset();
loadBMP(file);
}
//destructor
Bitmap::~Bitmap(){
if(colours!=0) {
delete[] colours;
}
if(pixelData!=0) {
delete[] pixelData;
}
}
//load a bitmap from a file and represent it correctly
//in memory
bool Bitmap::loadBMP(char *file) {
FILE *in; //file stream for reading
DWORD size; //size of the file
DWORD diff; //size of the image data
BYTE *tempPixelData; //temp storage for image data
LONG byteWidth; //the width in bytes of the image
LONG padWidth; //the width in bytes of the added image
int offset; //used for parsing the image data
int numColours; //total available colours
//bitmap is not loaded yet
loaded=false;
//make sure memory is not lost
if(colours!=0) {
delete[] colours;
}
if(pixelData!=0) {
delete[] pixelData;
}
//open the file for reading in binary mode
in=fopen(file,"rb");
//if the file does not exist return in error
if(in==NULL) {
error="File not found";
fclose(in);
return false;
}
//read in the entire BITMAPFILEHEADER
fread(&bmfh,sizeof(BITMAPFILEHEADER),1,in);
//check for the magic number that says this is a bitmap
if(bmfh.bfType!=BITMAP_MAGIC_NUMBER) {
error="File is not in DIB format";
fclose(in);
return false;
}
//read in the entire BITMAPINFOHEADER
fread(&bmih,sizeof(BITMAPINFOHEADER),1,in);
//save the width, height and bits per pixel for external use
width=bmih.biWidth;
height=bmih.biHeight;
bpp=bmih.biBitCount;
//calculate the size of the image data with padding
size=bmfh.bfSize-bmfh.bfOffBits;
//calculate the number of available colours
numColours=1<<bmih.biBitCount;
//if the bitmap is not 8 bits per pixel or more
//return in error
if(bpp<8) {
error="File is not 8 or 24 bits per pixel";
fclose(in);
return false;
}
//load the palette for 8 bits per pixel
if(bpp==8) {
colours=new RGBQUAD[numColours];
fread(colours,sizeof(RGBQUAD),numColours,in);
}
//set up the temporary buffer for the image data
tempPixelData=new BYTE[size];
//exit if there is not enough memory
if(tempPixelData==NULL) {
error="Not enough memory to allocate a temporary buffer";
fclose(in);
return false;
}
//read in the entire image
fread(tempPixelData,sizeof(BYTE),size,in);
//close the file now that we have all the info
fclose(in);
//calculate the witdh of the final image in bytes
byteWidth=padWidth=(LONG)((float)width*(float)bpp/8.0);
//adjust the width for padding as necessary
while(padWidth%4!=0) {
padWidth++;
}
//calculate the actual size of the image
diff=height*byteWidth;
//allocate the buffer for the final image data
pixelData=new BYTE[diff];
//exit if there is not enough memory
if(pixelData==NULL) {
error="Not enough memory to allocate an image buffer";
delete[] tempPixelData;
fclose(in);
return false;
}
//image parser for a reversed image
if(height>0) {
int j=0;
//set the offset equal to the padding size
offset=padWidth-byteWidth;
//count backwards so you start at the front of the image
for(int i=size-1;i>=0;i--) {
//jump over the padding at the start of a new line
if((i+1)%padWidth==0) {
i-=offset;
}
//transfer the data
*(pixelData+j)=*(tempPixelData+i);
//counter to count forward in the final buffer
j++;
}
}
//image parser for a forward image
else {
//get the absolute value of height
height=height*-1;
//offset is used to count lines
offset=0;
do {
//copy one line and ignore the padding
memcpy((pixelData+(offset*byteWidth)),(tempPixelData+(offset*padWidth)),byteWidth);
//next line
offset++;
} while(offset<height);
}
//clean up memory
delete[] tempPixelData;
//bitmap is now loaded
loaded=true;
error="Bitmap loaded";
//return success
return true;
}
//function to set the inital values
void Bitmap::reset(void) {
loaded=false;
colours=0;
pixelData=0;
error="";
}
And my changes for lesson6:
#include "Bitmap.h"
.
.
.
int LoadGLTextures() // Load Bitmaps And Convert To Textures
{
int Status=FALSE; // Status Indicator
Bitmap image; // Create Storage Space For The Texture
// Load The Bitmap, Check For Errors, If Bitmap''s Not Found Quit
if (image.loadBMP("Data\\NeHe.bmp"))
{
Status=TRUE; // Set The Status To TRUE
glGenTextures(1, &texture[0]); // Create The Texture
// Typical Texture Generation Using Data From The Bitmap
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, image.width, image.height, 0, GL_RGB, GL_UNSIGNED_BYTE, image.pixelData);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
return Status; // Return The Status
}
And here is lesson10 for comparison.
#include "Bitmap.h"
.
.
.
int LoadGLTextures() // Load Bitmaps And Convert To Textures
{
int Status=FALSE; // Status Indicator
Bitmap image;
// Load The Bitmap, Check For Errors, If Bitmap''s Not Found Quit
if (image.loadBMP("Data/Mud.bmp"))
{
Status=TRUE; // Set The Status To TRUE
glGenTextures(3, &texture[0]); // Create Three Textures
// Create Nearest Filtered Texture
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, image.width, image.height, 0, GL_RGB, GL_UNSIGNED_BYTE, image.pixelData);
// Create Linear Filtered Texture
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, image.width, image.height, 0, GL_RGB, GL_UNSIGNED_BYTE, image.pixelData);
// Create MipMapped Texture
glBindTexture(GL_TEXTURE_2D, texture[2]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image.width, image.height, GL_RGB, GL_UNSIGNED_BYTE, image.pixelData);
}
return Status; // Return The Status
}
Maybe it is something simple that I overlooked. Anyway thanks for looking.
---
Make it work.
Make it fast.
"I’m happy to share what I can, because I’m in it for the love of programming. The Ferraris are just gravy, honest!" --John Carmack: Forward to Graphics Programming Black Book