Dx9 vs opengl Texture Lock

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Dx9 vs opengl Texture Lock

Post by omaremad »

Just wanted to point out a bug where opengl driver when locking any texture always converts to rgba8 even if the texture is a 16 bit fixed or floating point one,.

Dx textures just return a pointer to the data rather than doing the rgba8 conversion.
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

The dx version doesnt even use IImage as a intermediate to generate the pointer.

Code: Select all


void* COpenGLTexture::lock(bool readOnly, u32 mipmapLevel)
{
	// store info about which image is locked
	IImage* image = (mipmapLevel==0)?Image:MipImage;
	ReadOnlyLock |= readOnly;
	MipLevelStored = mipmapLevel;

	// if data not available or might have changed on GPU download it
	if (!image || IsRenderTarget)
	{
		// prepare the data storage if necessary
		if (!image)
		{
			if (mipmapLevel)
			{
				u32 i=0;
				u32 width = TextureSize.Width;
				u32 height = TextureSize.Height;
				do
				{
					if (width>1)
						width>>=1;
					if (height>1)
						height>>=1;
					++i;
				}
				while (i != mipmapLevel);
				MipImage = image = new CImage(ECF_A8R8G8B8, core::dimension2du(width,height));
			}
			else
				Image = image = new CImage(ECF_A8R8G8B8, ImageSize);
			ColorFormat = ECF_A8R8G8B8;
		}
		if (!image)
			return 0;

		u8* pixels = static_cast<u8*>(image->lock());
		if (!pixels)
			return 0;

		// we need to keep the correct texture bound later on
		GLint tmpTexture;
		glGetIntegerv(GL_TEXTURE_BINDING_2D, &tmpTexture);
		glBindTexture(GL_TEXTURE_2D, TextureName);

		// allows to read pixels in top-to-bottom order
#ifdef GL_MESA_pack_invert
		if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_MESA_pack_invert))
			glPixelStorei(GL_PACK_INVERT_MESA, GL_TRUE);
#endif

		// download GPU data as ARGB8 to pixels;
		glGetTexImage(GL_TEXTURE_2D, mipmapLevel, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);

#ifdef GL_MESA_pack_invert
		if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_MESA_pack_invert))
			glPixelStorei(GL_PACK_INVERT_MESA, GL_FALSE);
		else
#endif
		{
			// opengl images are horizontally flipped, so we have to fix that here.
			const s32 pitch=image->getPitch();
			u8* p2 = pixels + (image->getDimension().Height - 1) * pitch;
			u8* tmpBuffer = new u8[pitch];
			for (u32 i=0; i < image->getDimension().Height; i += 2)
			{
				memcpy(tmpBuffer, pixels, pitch);
				memcpy(pixels, p2, pitch);
				memcpy(p2, tmpBuffer, pitch);
				pixels += pitch;
				p2 -= pitch;
			}
			delete [] tmpBuffer;
		}
		image->unlock();

		//reset old bound texture
		glBindTexture(GL_TEXTURE_2D, tmpTexture);
	}
	return image->lock();
}
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Re: Dx9 vs opengl Texture Lock

Post by robmar »

Is it a bug, or a feature? There´s a flag used to create the irrlicht device, to force ARGB8 mode, I think what youy´re seeing is a default mode only used if the data is no longer available, as its cached, I guess, no?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Dx9 vs opengl Texture Lock

Post by hybrid »

It's basically a not yet fully implemented feature, so more a bug than a feature in the current state. Correct behavior would be to convert the d3d textures as well, though, as we usually don't give access to the floating point textures so far.
Post Reply