/*************************************************************************** lodtexture.cpp - Texture with multiple Levels Of Detail ------------------- begin : do okt 28 2004 copyright : (C) 2004 by CJP email : cornware-cjp@users.sourceforge.net ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include "lodtexture.h" CLODTexture::CLODTexture(CDataManager *manager) : CTexture(manager) { m_Texture2 = m_Texture3 = m_Texture4 = 0; } CLODTexture::~CLODTexture() { unload(); } void CLODTexture::unload() { if(!isLoaded()) return; CTexture::unload(); glDeleteTextures(1, &m_Texture2); glDeleteTextures(1, &m_Texture3); glDeleteTextures(1, &m_Texture4); m_Texture2 = m_Texture3 = m_Texture4 = 0; } RGBImageRec *CLODTexture::loadFromImage(RGBImageRec *in_image, int xs, int ys) { in_image = CTexture::loadFromImage(in_image, xs, ys); RGBImageRec *image = scaleImage(in_image, xs/2, ys/2); if(image==NULL) { m_Texture2 = m_Texture; sizex2 = m_Sizex; sizey2 = m_Sizey; } else { glGenTextures(1, &m_Texture2); glBindTexture(GL_TEXTURE_2D, m_Texture2); if(image->format == 1) //RGBA {glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, image->sizeX, image->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->data);} else //Assume RGB {glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, image->sizeX, image->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image->data);} glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); if(m_TextureSmooth) { glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); } else { glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); } sizex2 = image->sizeX; sizey2 = image->sizeY; freeImage(in_image); in_image = image; } image = scaleImage(in_image, xs/4,ys/4); if(image==NULL) { m_Texture3 = m_Texture2; sizex3 = sizex2; sizey3 = sizey2; } else { glGenTextures(1, &m_Texture3); glBindTexture(GL_TEXTURE_2D, m_Texture3); if(image->format == 1) //RGBA {glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, image->sizeX, image->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->data);} else //Assume RGB {glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, image->sizeX, image->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image->data);} glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); if(m_TextureSmooth) { glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); } else { glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); } sizex3 = image->sizeX; sizey3 = image->sizeY; freeImage(in_image); in_image = image; } image = scaleImage(in_image, xs/8,ys/8); if(image==NULL) { m_Texture4 = m_Texture3; sizex4 = sizex3; sizey4 = sizey3; } else { glGenTextures(1, &m_Texture4); glBindTexture(GL_TEXTURE_2D, m_Texture4); if(image->format == 1) //RGBA {glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, image->sizeX, image->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->data);} else //Assume RGB {glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, image->sizeX, image->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image->data);} glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); if(m_TextureSmooth) { glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); } else { glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); } sizex4 = image->sizeX; sizey4 = image->sizeY; freeImage(in_image); in_image = image; } return in_image; } int CLODTexture::getSizeX(int i) const { switch(i) { case 1: return m_Sizex; case 2: return sizex2; case 3: return sizex3; case 4: return sizex4; } return 0; } int CLODTexture::getSizeY(int i) const { switch(i) { case 1: return m_Sizey; case 2: return sizey2; case 3: return sizey3; case 4: return sizey4; } return 0; } void CLODTexture::draw(int lod) const { if (getSizeX(lod) <= 4 || getSizeY(lod) <= 4) {printf(" Error: trying to draw a too small texture:\n" " lod=%d, x=%d, y=%d\n", lod, getSizeX(lod), getSizeY(lod)); return;} switch(lod) { case 1: glBindTexture(GL_TEXTURE_2D, m_Texture ); break; case 2: glBindTexture(GL_TEXTURE_2D, m_Texture2); break; case 3: glBindTexture(GL_TEXTURE_2D, m_Texture3); break; case 4: glBindTexture(GL_TEXTURE_2D, m_Texture4); } } unsigned int CLODTexture::getTextureID(int lod) const { switch(lod) { case 1: return m_Texture; break; case 2: return m_Texture2; break; case 3: return m_Texture3; break; case 4: return m_Texture4; } return 0; }