Rotation quality

Is there anything I can do about the quality of opengl rotation? I’m rendering some sprites and especially these asteroids get ugly borders when rotated.

Here’s a screenshot:
http://img332.imageshack.us/img332/7735/asteroids3rn.png

Anyone? :frowning:
There has to be somekind of switch that doesn’t blend/modify the borders at all but just rotates the raw texture data?

I tried GL_NEAREST filter in texture loading and it got rid from the grey border but it looks a bit too rough. Maybe I need mipmapping or something?

What color is your texture data that is getting blended out? If it’s white, or grey, you might try setting it to be black. That won’t eliminate the problem, but it should change the “border” around your asteroids to be a color that’s a bit less distracting.

What it looks like is happening is that your filtering is including some texels that you weren’t expecting to be visible. That’s why when you use NEAREST filtering you don’t see a border.

Mipmapping might help too (it’s certainly worth a try), but I wouldn’t expect a miracle.

– Ben

The outer pixels were just shades of gray ranging from ~(25,25,25) to ~(60,60,60). I tried adding completely black 2px wide outlines to them and especially with outer outline it improved quite a bit. But I dont wanna add 2px outline to all my images, and it’s still not perfect, so I’m hoping there’s some other solution.

I also tried mip-mapping - but i didn’t see any difference at all:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat, width, height, format, GL_UNSIGNED_BYTE, data);

Should mipmaps simply work this way, by just changing the glTexImage to gluBuildMipmaps (and filters), or do I have to add changes to anywhere else too?

Here’s a screenie of zoomed and outlined asteroids:

Thanks for your help.

You have alpha in your texture ? Change the alpha of the asteroid border pixels to 0.

hmm, I’m not sure what you mean. Yeah the images are PNG’s which have alpha channel (created with Photoshop), but none of the actual asteroid pixels are translucent. And when I added the black outlines I made sure they’re 100% black.

Here’s some code snippets how I do things, maybe someone spots something I’ve done wrong:

// Setup OpenGL for orthographic mode (2D)

glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (double)width, (double)height, 0.0, -1.0, 1.0);

// Setting up the sprite rendering state

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);	//GL_MODULATE
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

// Texture loading
</font><blockquote><font size=“1” face=“Verdana, Arial”>code:</font><hr /><pre style=“font-size:x-small; font-family: monospace;”>glBindTexture(GL_TEXTURE_2D, ID);
if(GLContext.getCapabilities().OpenGL12) {
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
} // else GL_CLAMP??
if(minFilter == GL_LINEAR_MIPMAP_LINEAR

remove all the C++ logical or operators from your code. The POS html parser can’t handle them…

For some reason the post came unregistered and I can’t edit it, anyway here’s the texture loading(which got snipped):

</font><blockquote><font size=“1” face=“Verdana, Arial”>code:</font><hr /><pre style=“font-size:x-small; font-family: monospace;”>glBindTexture(GL_TEXTURE_2D, ID);
if(GLContext.getCapabilities().OpenGL12) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
} // else GL_CLAMP??
if(minFilter == GL_LINEAR_MIPMAP_LINEAR

:mad:
Annoying that preview shows the post just right.
If any mod. sees this, please delete or edit my previous posts.
Hope it works now…

glBindTexture(GL_TEXTURE_2D, ID);
		if(GLContext.getCapabilities().OpenGL12) {
			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
		} // else GL_CLAMP??
		if(minFilter == GL_LINEAR_MIPMAP_LINEAR {OR} minFilter == GL_LINEAR_MIPMAP_NEAREST) {
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
			gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat, width, height, format, GL_UNSIGNED_BYTE, data);
		} else {
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, data);
		}

Looks like linear filtering is bleeding the black border pixels into the asteroid.

You shouldn’t need a black border if you set your alpha mask up right. As Zbuffer said, make sure your image alpha masks the complete cutout of the asteroid.

You can combine the alpha test with alpha blending to smooth the results, but beware of the blending artifacts that go with it…

I’m still confused. I’m not using opengl’s masking at all, the images have just alpha channel in them and all the pixels which are not fully transparent, are 100% opaque.

I attached one of the asteroid images here (part of an animation), so you can see the image for yourself:

Maybe I’m not understanding something. :rolleyes:

The problem is following: If filtering other than GL_NEAREST is enabled and texture is not mapped in such way that pixel does have single texel positioned exactly at pixel coordinates, pixel color and alpha is calculated by weighted sum of colors and alphas from several texels (4 in case of GL_LINEAR filtering without mipmapping).

What will hapen depends on if texels used for pixel color/alpha calculation are within the asteroid image inside your texture or if they are outside of the asteroid image.

  1. If all texels are outside, result is fully transparent and it looks ok.
  2. If all texels are inside, result is fully opaque and its color is composed only from texels from within the asteroid so this looks ok too.
  3. If some texels are inside and some outside, result is partialy transparent and its color is composed from colors that are within the asteroid and from colors outside of it (that gray color). Result is the ugly border.

The simplest way to get rid of them for GL_LINEAR filtering is to change alpha of asteroid texels that are part of asteroid border (currently they have asteroid color and opaque alpha) to fully transparent. If you do that then the third situation (some texels from outside and some from inside) will have partialy transparent alpha and color that is composed from colors entirely from within the asteroid so this should look ok.

With use of fragment programs it can be probably done even with your current texture however it will be very inefficientl in that case.

Thanks for a very detailed post, it’s getting quite clear now.

I just noticed that zbuffer actually said the same thing earlier:

You have alpha in your texture ? Change the alpha of the asteroid border pixels to 0.

I just somehow interpreted the zero being fully opaque and got stuck to that thought. :rolleyes:

Thanks everyone.