예제 #1
0
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);
}
예제 #2
0
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;
}
예제 #3
0
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);
}
예제 #4
0
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
예제 #5
0
static inline u32 CorrectDimension( u32 dimension )
{
	static const u32 MIN_TEXTURE_DIMENSION = 1;
	return Max( GetNextPowerOf2( dimension ), MIN_TEXTURE_DIMENSION );
}