Original Post
I'm having some trouble mapping a bitmap to one side of a cube. Problem 1: When I'm mapping, the cube rotates really slowly. I've found that it's becuase of the 'glTexParameteri' function calls. Where should I be putting these function calls? Problem 2: I'm not seeing the texture on the cube (rotating) when I try to texture. I figure its either my init function, my vertices and the related tex coords, or my bitmap loading function, so I'm providing them here for fixing, hints, tips or criticism. Whatever you feel like dishing out (as long as its related to my code :D) If anyone can help, maybe see something that I've missed, or messed up, your help is appreciated. [smile] [Edited by - Endar on October 16, 2005 8:46:10 AM]
/**
* Base class that represents a texture.
*/
class ITexture : public IMBase
{
protected:
unsigned int m_texDataSize; ///< The size of the data (in bytes)
unsigned char* m_texData; ///< The texture data
video::dimension2d m_size; ///< The size of the picture (width and height)
public:
/**
* Constructor
* \param r A reference to a CReadFile object that is open to a valid file.
* \param d An unsigned char pointer to the image data.
* Note:: A seperate copy of the data is made for the texture, so the memory
* pointed to by the param can be free'd after being passed here.
*/
ITexture(video::dimension2d& image_size, unsigned int size, unsigned char* d)
: m_size(image_size), m_texDataSize(size)
{
m_texData = new unsigned char[size];
memcpy(m_texData, d, size); // copy the data across
}
/**
* Destructor
*/
virtual ~ITexture()
{
delete m_texData;
}
/**
* Return the height and width of the texture.
* \return The height and width of the texture.
*/
video::dimension2d getSize() const
{
return m_size;
}
/**
* Apply the texture.
*/
virtual void apply() = 0;
};
/**
* A wrapper class to represent an OpenGL texture.
*/
class COpenGLTexture : public ITexture
{
private:
unsigned int m_texture; ///< The texture object
public:
/**
* Constructor
* \param texture The openGL reference to this texture
* \param image_size The dimensions of the image
* \param size The size of the image data (in bytes)
* \param d A pointer to the image data
*/
COpenGLTexture(unsigned int texture, video::dimension2d& image_size, unsigned int size, unsigned char* d)
: ITexture(image_size, size, d), m_texture(texture)
{
}
/**
* Apply the texture.
*/
void apply()
{
// apply the texture
glBindTexture(GL_TEXTURE_2D, m_texture);
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, GL_RGB, (int)m_size.width, (int)m_size.height,
0, GL_RGB, GL_UNSIGNED_BYTE, m_texData);
}
};
// The cube vertices.
// The order of params is (position, normal, color, u, v)
// The normal really isn't being used right now. So, its probably kinda
// (completely messed up)
util::array<scene::CVertex3d> arr;
arr.resize(8);
arr[0] = scene::CVertex3d( util::CVector3d(-0.5f, 0.5f, 0.5f), util::CVector3d(-0.5f, 0.5f, 0.5f),
video::CColor(1.0f,0.0f,0.0f), 0.0f, 0.0f);
arr[1] = scene::CVertex3d( util::CVector3d(-0.5f, -0.5f, 0.5f), util::CVector3d(-0.5f, -0.5f, 0.5f),
video::CColor(0.0f,1.0f,0.0f), 0.0f, 1.0f);
arr[2] = scene::CVertex3d( util::CVector3d( 0.5f, 0.5f, 0.5f), util::CVector3d( 0.5f, 0.5f, 0.5f),
video::CColor(0.0f,0.0f,1.0f), 1.0f, 0.0f);
arr[3] = scene::CVertex3d( util::CVector3d( 0.5f, -0.5f, 0.5f), util::CVector3d( 0.5f, -0.5f, 0.5f),
video::CColor(1.0f,1.0f,0.0f), 1.0f, 1.0f);
arr[4] = scene::CVertex3d( util::CVector3d( 0.5f, -0.5f, -0.5f), util::CVector3d( 0.5f, -0.5f, -0.5f),
video::CColor(1.0f,0.0f,1.0f), 0.0f, 0.0f);
arr[5] = scene::CVertex3d( util::CVector3d( 0.5f, 0.5f, -0.5f), util::CVector3d( 0.5f, 0.5f, -0.5f),
video::CColor(0.0f,1.0f,1.0f), 0.0f, 0.0f);
arr[6] = scene::CVertex3d( util::CVector3d(-0.5f, 0.5f, -0.5f), util::CVector3d(-0.5f, 0.5f, -0.5f),
video::CColor(0.5f,0.0f,0.5f), 0.0f, 0.0f);
arr[7] = scene::CVertex3d( util::CVector3d(-0.5f, -0.5f, -0.5f), util::CVector3d(-0.5f, -0.5f, -0.5f),
video::CColor(0.0f,0.5f,0.5f), 0.0f, 0.0f);
// these are the indexes for the triangles
util::array<unsigned int> index;
index.resize(36);
unsigned int temp[36] = { 1,0,2, 1,2,3, 3,2,4, 2,5,4, 0,1,7,
0,7,6, 0,6,2, 6,5,2, 6,7,4, 6,4,5, 1,3,7, 7,3,4 };
// my OGL init function
// (The OGL function calls are at the bottom)
bool COpenGLDriver::initDriver(const video::dimension2d& screenSize)
{
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // size of the structure
1, // version. Always set to 1
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support opengl
PFD_DOUBLEBUFFER, // support double buffering
PFD_TYPE_RGBA, // RGBA color mode
32, // 32-bit color mode
0, 0, 0, 0, 0, 0, // ignore color bits, not used
0, // no alpha buffer
0, // ignore shift bit
0, // no accumulation buffer
0, 0, 0, 0, // ignore accumulation bits
16, // 16-bit z-buffer size
0, // no stencil buffer
0, // no auxillary buffer
PFD_MAIN_PLANE, // main drawing plane
0, // reserved
0, 0, 0 // layer masks ignored
};
// if get hdc fails
if( !(hDC = GetDC(Window)) ){
util::Message::print("COpenGLDriver::initDriver: Cannot create a GL device context.");
return false;
}
// chose best matching pixel format, return index
if( !(nPixelFormat=ChoosePixelFormat(hDC, &pfd)) ){
util::Message::print("COpenGLDriver::initDriver: Cannot find a suitable pixel format.");
return false;
}
// set pixel format to device context
if( !SetPixelFormat(hDC, nPixelFormat, &pfd) ){
util::Message::print("COpenGLDriver::initDriver: Cannot set the pixel format.");
return false;
}
// create rendering context
if( !(hRC=wglCreateContext(hDC)) ){
util::Message::print("COpenGLDriver::initDriver: Cannot create a GL rendering context.");
return false;
}
// activate rendering context
if( !wglMakeCurrent(hDC, hRC) ){
util::Message::print("COpenGLDriver::initDriver: Cannot activate GL rendering context.");
return false;
}
glShadeModel(GL_SMOOTH); // enable smooth shading
glDisable(GL_LIGHTING); // lighting disabled
glFrontFace(GL_CW); // clockwise polygons are out, I think ??? FIXME
glEnable(GL_CULL_FACE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// really nice perspective calculations
glClearDepth(1.0f); // set gl clear depth
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_TEXTURE_2D); // enable 2D texturing
util::Message::print("COpenGLDriver::COpenGLDriver: OpenGL was initialised successfully.");
resizeWindow(screenSize); // set the viewport and aspect ratios properly
return true; // init went well
}
/**
* Load an bitmap file for use in openGL.
* \param f A reference to a CReadFile object that is open to a bitmap file.
* \param dim A reference to store the height and width of the bitmap
* \param size A pointer to an unsigned int to store the size of the bitmap (in bytes)
*/
unsigned char* OGLLoadBitmapFile(io::CReadFile& f, video::dimension2d& dim, unsigned int* size)
{
BITMAPFILEHEADER bitmapFileHeader; // bitmap file header
BITMAPINFOHEADER bitmapInfoHeader; // bitmap info header
unsigned char* bitmapImage; // bitmap image data
// check if the file is valid
if( !f.isOpen() ){
util::Message::print("OGLLoadBitmapFile: \"%s\" is not a valid filename.", f.getFilename() );
f.closeFile(); // close the file
return NULL;
}
// read the bitmap file header
f.read(&bitmapFileHeader, sizeof(BITMAPFILEHEADER) );
// verify that this is a bitmap by checking for the universal bitmap id
if( bitmapFileHeader.bfType != 0x4d42 ){
util::Message::print("OGLLoadBitmapFile: \"%s\" is not a valid bitmap.", f.getFilename() );
f.closeFile(); // close the file
return NULL;
}
// read the bitmap information header
f.read(&bitmapInfoHeader, sizeof(BITMAPINFOHEADER) );
// assign the size
dim.height = bitmapInfoHeader.biHeight;
dim.width = bitmapInfoHeader.biWidth;
// move the file pointer to the beginning of bitmap data
f.seek( bitmapFileHeader.bfOffBits, SEEK_SET );
// allocate enough memory for the bitmap image data
bitmapImage = new unsigned char[bitmapInfoHeader.biSizeImage];
// vefiy memory alloc
if( !bitmapImage ){
util::Message::print("OGLLoadBitmapFile: could not allocate enough memory for bitmap.");
f.closeFile(); // close the file
return NULL;
}
// read the texture data from file into the allocated mem
f.read(bitmapImage, sizeof(bitmapInfoHeader.biSizeImage) );
char tempRGB;
// swap the R and B values to get RGB since the bitmap color format is in BGR
for(int i=0; i < bitmapInfoHeader.biSizeImage; i+= 3 ){
tempRGB = bitmapImage;
bitmapImage = bitmapImage[i+2];
bitmapImage[i+2] = tempRGB;
}
*size = bitmapInfoHeader.biSizeImage; // the size (in bytes) of the image data
return bitmapImage; // return the image data
}