I meant, do we want to use sep. images instead of spritesheets for now during development, to avoid the power-of-2-messing-up-sheet problem? Then we can pad individual images w/ blank data to achieve power of two.
Actually, my OpenGL + non-standard-LoadBMP bit here can load non-power-of-twos and then it scales them to power of two for usage. IIRC, it scales the actual image part to fit when I draw on a shape. Mipmapping also works but is slower. (Been a while since I looked at this code.) You'll note the memory handling stuff is in C. The tutorial does it that way but I'm also sure I could do something like have a class and then pad the class w/ an array... This uses actual numbers though.
Code: Select all
bool Texture::loadTexture(string pfilename, bool mipmap) {
AUX_RGBImageRec* texImage[1];
BYTE* scaleTex = NULL;
memset(texImage, 0, sizeof(void*)*1);
float powerLog;
int powerOfTwo;
//int powerOfTwo2;
GLenum errored = 0;
int newWidth;
int newHeight;
bool scaleImage = false;
if (!(texImage[0] = LoadBMP(pfilename))) {
debug(("loadTexture() : LoadBMP returned null. Could not open file '" + pfilename + "' for read."));
return false;
}
glGenTextures(1, &theTexture);
glBindTexture(GL_TEXTURE_2D, theTexture);
width = texImage[0]->sizeX;
height = texImage[0]->sizeY;
newWidth = texImage[0]->sizeX;
newHeight = texImage[0]->sizeY;
if (!mipmap) {
//See if the image is a power of two. If it's not, mipmap it.
powerLog = log(texImage[0]->sizeX)/log(2);
powerOfTwo = roundFloat(powerLog);
if (powerOfTwo != powerLog) {
if (powerOfTwo < powerLog)
powerOfTwo++;
newWidth = (unsigned int)pow(2, powerOfTwo);
scaleImage = true;
}
powerLog = log(texImage[0]->sizeY)/log(2);
powerOfTwo = roundFloat(powerLog);
if (powerOfTwo != powerLog) {
if (powerOfTwo < powerLog)
powerOfTwo++;
newHeight = (unsigned int)pow(2, powerOfTwo);
scaleImage = true;
}
}
if (mipmap) {
errored = gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texImage[0]->sizeX,
texImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, texImage[0]->data);
if (errored) {
string str = (char*)gluErrorString(errored);
debug("Mipmap error: " + str);
MessageBox(NULL, "Mipmap error.", "a", MB_OK);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
} else if (scaleImage) {
scaleTex = (BYTE*)malloc(newWidth * newHeight * 3 * sizeof(BYTE));
if (!scaleTex) {
MessageBox(NULL, "Error allocating texture resize.", "err", MB_OK);
return false;
}
errored = gluScaleImage(GL_RGB, texImage[0]->sizeX, texImage[0]->sizeY, GL_UNSIGNED_BYTE,
texImage[0]->data, newWidth, newHeight, GL_UNSIGNED_BYTE, scaleTex);
if (errored) {
string str = (char*)gluErrorString(errored);
debug("Scale error: " + str);
MessageBox(NULL, "Scale error.", "a", MB_OK);
}
//width = newWidth;
//height = newHeight;
glTexImage2D(GL_TEXTURE_2D, 0, 3, newWidth,
newHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
scaleTex);
debug("Scaled " + pfilename);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, 3, texImage[0]->sizeX,
texImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
texImage[0]->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
if (texImage[0]) {
if (texImage[0]->data)
free(texImage[0]->data);
free(texImage[0]);
}
if (scaleTex)
free(scaleTex);
return true;
}