Howto: Add Anisotropic Filtering into Irrlicht 0.11, GL only

A forum to store posts deemed exceptionally wise and useful
Post Reply
disanti
Posts: 367
Joined: Sat Jan 17, 2004 1:36 am
Location: California, US
Contact:

Howto: Add Anisotropic Filtering into Irrlicht 0.11, GL only

Post by disanti »

Hello everyone, today I got bored and implemented Anisotropic filtering to Irrlicht.

All of the changes are made in: COpenGLTexture.cpp

List of changes:

After:

Code: Select all

#include "glext.h"
Put:

Code: Select all

#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
Replace function:

Code: Select all

void COpenGLTexture::copyTexture()
With:

Code: Select all

//! copies the the texture into an open gl texture.
void COpenGLTexture::copyTexture()
{
	glBindTexture(GL_TEXTURE_2D, TextureName);
	if (testError())
		os::Printer::log("Could not bind Texture", ELL_ERROR);

	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ImageSize.Width, 
		ImageSize.Height, 0, GL_BGRA_EXT , GL_UNSIGNED_BYTE, ImageData);
	if (testError())
		os::Printer::log("Could not glTexImage2D", ELL_ERROR);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	if (hasMipMaps)
	{
		s32 ret = 0;
		
		#ifndef DISABLE_MIPMAPPING
		ret = gluBuild2DMipmaps(GL_TEXTURE_2D, 4, ImageSize.Width, ImageSize.Height,
 		            GL_BGRA_EXT, GL_UNSIGNED_BYTE, ImageData);
		#endif

		if (ret)
		{
			#ifndef DISABLE_MIPMAPPING
			os::Printer::log("Could not create OpenGL texture mip maps.",
				(c8*)gluErrorString(ret), ELL_ERROR);
			#else
			os::Printer::log("Did not create OpenGL texture mip maps.", ELL_ERROR);
			#endif
		}
		else
		{
		 	if(!strstr((char*)glGetString(GL_EXTENSIONS), "GL_EXT_texture_filter_anisotropic"))
		 	{
		       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
			   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
 		    }
 		    else
 		    {
		 	   float maximumAnisotropy;
		 	   glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy);
		 	   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maximumAnisotropy);
			   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
			   //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	        }
		}
	}	
}
All of these changes are tested and work, compiles under Dev-Cpp, don't know about anything else at the moment.

Enjoy~ John DiSanti
________
ZX14 VS HAYABUSA
Last edited by disanti on Thu Feb 24, 2011 10:35 am, edited 1 time in total.
disanti
Posts: 367
Joined: Sat Jan 17, 2004 1:36 am
Location: California, US
Contact:

Post by disanti »

Please tell me someone tried it! This thing works beautifully! :)
________
Toyota Industries
Last edited by disanti on Thu Feb 24, 2011 10:36 am, edited 1 time in total.
puh
Posts: 356
Joined: Tue Aug 26, 2003 3:53 pm

Post by puh »

Hi, diasanti.
I've tried and it worked ok, at least my app starts and running without errors. With my eye i can not see any difference though.
[edit]Oh, i've just finished a test and i see a HUGE difference in guality of distant objects. Look this img: http://www.irrforge.org/images/e/ed/Ani ... tering.png (165 KB)
And btw as i see you hardcoded level of anisotropy to be 8, good style would be to read videocard capability and ask user chose this value. At least this would be better IMHO.
Thank you very much for this work anyway!
Electron
Posts: 874
Joined: Sun Mar 14, 2004 12:05 am
Location: Massachusetts USA

Post by Electron »

Code: Select all

glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy);
looks to me like its getting the max from the videocard, though ur right that the user should be able to set it
You do a lot of programming? Really? I try to get some in, but the debugging keeps me pretty busy.

Crucible of Stars
TheRLG
Posts: 372
Joined: Thu Oct 07, 2004 11:20 pm

Post by TheRLG »

puh wrote:Hi, diasanti.
I've tried and it worked ok, at least my app starts and running without errors. With my eye i can not see any difference though.
[edit]Oh, i've just finished a test and i see a HUGE difference in guality of distant objects. Look this img: http://www.irrforge.org/images/e/ed/Ani ... tering.png (165 KB)
And btw as i see you hardcoded level of anisotropy to be 8, good style would be to read videocard capability and ask user chose this value. At least this would be better IMHO.
Thank you very much for this work anyway!
wow, thats a nice little difference there. can anyone get this to Dx too?
disanti
Posts: 367
Joined: Sat Jan 17, 2004 1:36 am
Location: California, US
Contact:

Post by disanti »

I would make it in DirectX if I knew how to but I don't know the first thing about programming with DirectX. Thanks for trying it out! :)
________
No2 vaporizer
Last edited by disanti on Thu Feb 24, 2011 10:37 am, edited 1 time in total.
grey lantern

Post by grey lantern »

I have it running in DX8 drivers.. (pass an int for low/med/max to abstract the varying levels on different cards) I will post the code when I get time, if niko hasn't added it in the meantime, sorry no time at the moment but dig out dx8driver.cpp or (dx9) and add the relevent setup code to the texture filter area.. get this info from the dxsdk documentation, don't forget caps checking!

rgds
Guest

Post by Guest »

Coool, works straight out of the box with OGL and DevCpp. And it does make a huge difference visually. Framerate stay OK with GF4/Athlon2.4. Thanks a lot.
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

I just put this in for DirectX9 in IrrSpintz

Here's some screenshots -

BILINEAR -

Image

TRILINEAR -

Image

16x ANISTROPIC -

Image

If you aren't seeing a difference, there isn't much between bilinear and trilinear. however, in the anisotropic filtering image, look at the mountain in the distance, specifically the left side of it, it's much crisper then the other 2.
Image
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

I'm trying to put this in so it can be changeable. In DX, these renderstates are set up if they changer per material. In OpenGL, with this code, it's done when the textures are loaded, and you can't toggle it. I'm trying to figure that out.
Image
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

Do you know how to turn off anisotropic filtering in OpenGL?
Image
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

I got it

Instead of the changes you proposed, I did this in COpenGLDriver::setBasicRenderStates

Code: Select all

	// bilinear, trilinear, anisotropic filtering
	if( resetAllRenderstates || 
		lastmaterial.BilinearFilter != material.BilinearFilter ||
		lastmaterial.TrilinearFilter != material.TrilinearFilter ||
		lastmaterial.AnisotropicFilter != material.AnisotropicFilter )
	{
		if( material.AnisotropicFilter )
		{
			float maxAnisotropyLevel;
			glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyLevel );
			float anisotropyLevel = (float)material.AnisotropyLevel / 16.0f;
			anisotropyLevel = anisotropyLevel < maxAnisotropyLevel ? anisotropyLevel : maxAnisotropyLevel;
			glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropyLevel ); 
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); 
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 			
		}
		else if( material.TrilinearFilter )
		{
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
			glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0.0f );
		}
		else if( material.BilinearFilter )
		{
			glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
			glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
			glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0.0f );
		}
		else
		{
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
			glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0.0f );
		}
	}
I have some other changes, like modifying SMaterial.h so that there is now a enum for EMF_ANISOTROPIC_FILTER as well as AnisotropicFilter and AnisotropyLevel variables in the SMaterial structure.

So next version of IrrSpintz will have Anisotropic Filtering for OpenGL, DX8 and DX9
Image
Post Reply