bool GLTexture2D::Create() { arx_assert(!tex, "leaking OpenGL texture"); glGenTextures(1, &tex); // Set our state to the default OpenGL state wrapMode = TextureStage::WrapRepeat; mipFilter = TextureStage::FilterLinear; minFilter = TextureStage::FilterNearest; magFilter = TextureStage::FilterLinear; Vec2i nextPowerOfTwo(GetNextPowerOf2(size.x), GetNextPowerOf2(size.y)); storedSize = renderer->hasTextureNPOT() ? size : nextPowerOfTwo; isNPOT = (size != nextPowerOfTwo); return (tex != GL_NONE); }
static u32 GetTextureBlockWidth( u32 dimension, ETextureFormat texture_format ) { DAEDALUS_ASSERT( GetNextPowerOf2( dimension ) == dimension, "This is not a power of 2" ); // Ensure that the pitch is at least 16 bytes while( CalcBytesRequired( dimension, texture_format ) < 16 ) { dimension *= 2; } return dimension; }
bool GLTexture2D::Create() { arx_assert(!tex, "leaking OpenGL texture"); glGenTextures(1, &tex); // Set our state to the default OpenGL state wrapMode = TextureStage::WrapRepeat; mipFilter = TextureStage::FilterLinear; minFilter = TextureStage::FilterNearest; magFilter = TextureStage::FilterLinear; if(GLEW_ARB_texture_non_power_of_two) { storedSize = size; } else { storedSize = Vec2i(GetNextPowerOf2(size.x), GetNextPowerOf2(size.y)); } CHECK_GL; return (tex != GL_NONE); }
void GLTexture2D::Upload() { arx_assert(tex != GL_NONE); glBindTexture(GL_TEXTURE_2D, tex); renderer->GetTextureStage(0)->current = this; #ifdef HAVE_GLES #define GL_LUMINANCE8 GL_LUMINANCE #define GL_ALPHA8 GL_ALPHA #define GL_LUMINANCE8_ALPHA8 GL_LUMINANCE_ALPHA #define GL_RGB8 GL_RGB #define GL_BGR GL_RGB #define GL_RGBA8 GL_RGBA #endif GLint internal; GLenum format; if(mFormat == Image::Format_L8) { internal = GL_LUMINANCE8, format = GL_LUMINANCE; } else if(mFormat == Image::Format_A8) { internal = GL_ALPHA8, format = GL_ALPHA; } else if(mFormat == Image::Format_L8A8) { internal = GL_LUMINANCE8_ALPHA8, format = GL_LUMINANCE_ALPHA; } else if(mFormat == Image::Format_R8G8B8) { internal = GL_RGB8, format = GL_RGB; } else if(mFormat == Image::Format_B8G8R8) { #ifdef HAVE_GLES mImage.ConvertTo(Image::Format_R8G8B8); internal = GL_RGB8, format = GL_RGB; #else internal = GL_RGB8, format = GL_BGR; #endif } else if(mFormat == Image::Format_R8G8B8A8) { internal = GL_RGBA8, format = GL_RGBA; } else if(mFormat == Image::Format_B8G8R8A8) { #ifdef HAVE_GLES mImage.ConvertTo(Image::Format_R8G8B8A8); internal = GL_RGBA8, format = GL_RGBA; #else internal = GL_RGBA8, format = GL_BGRA; #endif } else { arx_assert_msg(false, "Unsupported image format"); return; } #if 0 printf("GLTexture2D::Upload (%ix%i), Mipmaps=%s, Format=%s\n", size.x, size.y, (hasMipmaps())?"yes":"no", (format==GL_LUMINANCE)?"GL_L":(format==GL_ALPHA)?"GL_A":(format==GL_LUMINANCE_ALPHA)?"GL_LA":(format==GL_RGB)?"GL_RGB":"GL_RGBA" ); #endif #ifdef PANDORA0 if(hasMipmaps() && ((format==GL_RGB) || (format==GL_RGBA))) { // more Gamma on the Pandora mImage.QuakeGamma(1.6); }; #endif #ifdef HAVE_GLES if(hasMipmaps() && ((size.x>32) || (size.y>32))) { // downscale this texture ! if (mImage.DownScale()) { size.x = mImage.GetWidth(); size.y = mImage.GetHeight(); storedSize = Vec2i(GetNextPowerOf2(size.x), GetNextPowerOf2(size.y)); } } #endif if(hasMipmaps()) { glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); } // TODO handle GL_MAX_TEXTURE_SIZE #ifdef HAVE_GLES // convert to 16 bits some textures if (internal==GL_RGB8) { // convert 24bits RGB to 16bits 565 RGB unsigned char *temp = new unsigned char[mImage.GetWidth()*mImage.GetHeight()*2]; unsigned short *p = (unsigned short*)temp; unsigned char *s = mImage.GetData(); for (unsigned int y=0; y<mImage.GetHeight(); y++) for (unsigned int x=0; x<mImage.GetWidth(); x++) { unsigned short r = s[0]>>3, g = s[1]>>2, b = s[2]>>3; *(p++) = r<<11 | g<<5 | b; s+=3; } if(storedSize != size) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, storedSize.x, storedSize.y, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size.x, size.y, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, temp); } else { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.x, size.y, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, temp); } delete[] temp; } else
static inline u32 CorrectDimension( u32 dimension ) { static const u32 MIN_TEXTURE_DIMENSION = 1; return Max( GetNextPowerOf2( dimension ), MIN_TEXTURE_DIMENSION ); }