PDA

View Full Version : Antialiasing



schallkiste
03-26-2009, 12:49 AM
Hi, im new in this forum and new in openGL. i'm from germany and my english isn't well. but i' trying it as well as i can :)

My first goals in openGL are screensavers. Quick and you see something :) at first i wrote some "traces of fishes" ... nice colors, nice rotations und nice moves. but the problem i have is the antialiasing. it works, but it doesn't work. sounds paradoxical, but so it is ;) ...

the aa only works in context of the background. if there on the background other lines in color, the aa calculates still in context of the background.

i have a picture, but i can't upload it anywhere

to explain the construction:
BACKGROUND
LINE
AND THEN A LINE OVER THE FIRST LINE

on the interceptpoint, the aa isn't to the color of the first line, but to the backgound. this don't looks well ...

how can i fix this bug?

matchStickMan
03-26-2009, 01:35 AM
on the interceptpoint, the aa isn't to the color of the first line, but to the backgound. this don't looks well ...




I suspect you might have some z-fighting in your construction.

Could you try this:

BACKGROUND
glTranslatef(0.0, 0.0, 0.01f);
LINE
glTranslatef(0.0, 0.0, 0.01f);
AND THEN A LINE OVER THE FIRST LINE

Essentially you add a small z-offset between the two lines.
I hope that works.


ps: If you want really cool openGL screensavers, check out this site:

http://www.reallyslick.com/

It's got quite a few openGL screensavers and the really nice thing is that the source code is also provided.

have fun!

schallkiste
03-26-2009, 01:51 AM
Hi, thank you for the fast answer ... :)
this doesnt works ... thank you for the tip of this nice screensavers ...

I'am painting some thousands small lines in every directions and different colors ...

can i send you the code or the release to see the problem?

matchStickMan
03-26-2009, 02:19 AM
Hi schallkiste,

Could you try pasting the critical parts of your code on this thread so that we can have a look.

tnx.

schallkiste
03-26-2009, 03:03 AM
yes ....
:)
some code of the childfish-class


//I need to say, the code is quick and dirty ... thats only for playing

//The mother in this case is a point, who moves on x, y, and z-achsis
//like a ping/pong (Think at mystify in 2D, but here in 3D)
//In every pass of the infinity-loop, the mother ist on the next step and
//150 of this childfishes follow the mother
//the length of the traces are 300
void CChildFish::Paint(CCoord mother)
{
//This is the calculting of the mov of the childfish
//with acceleration und velocity fpr smoothed moves
//every fish has another accelertation an max-velocity
//so the fishswarm-move ist realy naturell
//you see, there are many many lines in every way
if(mother.GetX() > m_Coord[pos].GetX())
{
m_VX += m_A;
if(m_VX > m_MaxV)
{
m_VX = m_MaxV;
}
}
else if(mother.GetX() < m_Coord[pos].GetX())
{
m_VX -= m_A;
if(m_VX < -m_MaxV)
{
m_VX = -m_MaxV;
}
}

if(mother.GetY() > m_Coord[pos].GetY())
{
m_VY += m_A;
if(m_VY > m_MaxV)
{
m_VY = m_MaxV;
}
}
else if(mother.GetY() < m_Coord[pos].GetY())
{
m_VY -= m_A;
if(m_VY < -m_MaxV)
{
m_VY = -m_MaxV;
}
}

if(mother.GetZ() > m_Coord[pos].GetZ())
{
m_VZ += m_A;
if(m_VZ > m_MaxV)
{
m_VZ = m_MaxV;
}
}
else if(mother.GetZ() < m_Coord[pos].GetZ())
{
m_VZ -= m_A;
if(m_VZ < -m_MaxV)
{
m_VZ = -m_MaxV;
}
}

int posMem = pos;
pos++;
if(pos >= length)
{
pos = 0;
}
m_Coord[pos].SetX(m_Coord[posMem].GetX() + m_VX);
m_Coord[pos].SetY(m_Coord[posMem].GetY() + m_VY);
m_Coord[pos].SetZ(m_Coord[posMem].GetZ() + m_VZ);


float x = 0;
float y = 0;
float z = 0;

glBegin( GL_LINE_STRIP );

//This is only for blending in and out the strips/traces of fishes
float length2 = length / 2;

for(int i = 0; i < length; i++)
{
//this is nessecary, to begin and end at the right point in the array
//the pos moves in every step, so i need to begin at over poses
int currentPos = pos - i;
if(currentPos < 0)
{
currentPos += length;
}

x = m_Coord[currentPos].GetX();
y = m_Coord[currentPos].GetY();
z = m_Coord[currentPos].GetZ();

//This is only for blending in and out the strips/traces of fishes
float transparency = ((float)((length2 - abs(length2-i))/length))*5;
if(transparency > 1.0)
{
transparency = 1.0;
}
transparency *= 0.4;
//This color works fine, believe me :)
glColor4f((x+1000)/2000, (y+1000)/2000, (z+1000)/2000, transparency);

//This you need at the beginning
if(x != -9999)
{
//Here, the lines
//they are everywhere and in everey direction
glVertex3f(x, y, z);
}
}
glEnd();
}

an the main


//...
glClearColor( 0.0, 0.0,0.0, 0.0 );
glEnable( GL_DEPTH_TEST );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glFrustum( -400, 400, -400, 400, 100, 2100);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

glTranslatef(0,0,-1000);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LINE_SMOOTH);

//...

while(true)
{
Sleep(18);

if( !pollEvents() ) break;

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );


CCoord mother;
mother.SetX(pointX->GetPoint());
mother.SetY(pointY->GetPoint());
mother.SetZ(pointZ->GetPoint());

bool takeMother = true;
if(move != 0)
{
takeMother = true;
move--;
}
if(move == 0)
{
if(pause == 0)
{
xAng = ((float)(rand() % 100))/100;
yAng = ((float)(rand() % 100))/100;
zAng = ((float)(rand() % 100))/100;
ang = 0.5+(((float)(rand() % 200))/100);
pause = 100;
}
}

for(int i = 0 ; i < count; i++)
{

fish[i].Paint(mother);
}

glRotatef(currentAng,currentXAng,currentYAng,curre ntZAng);
// ... here a long calculation for the rotation
if(pause != 0)
{
pause--;
}
if(pause == 0)
{
if(move == 0)
{
move = 200;
}
}

SDL_GL_SwapBuffers(); // Bildbuffer vertauschen
}

Jan
03-26-2009, 03:04 AM
Do you create a multisampled backbuffer or do you use the old glEnable (GL_SMOOTH_LINES) ?

schallkiste
03-26-2009, 03:05 AM
I use the glEnable (GL_SMOOTH_LINES) ...
how can i use the multisampled backbuffer? :)

Jan
03-26-2009, 03:11 AM
Ah, i was too late.

Yes, you use GL_LINE_SMOOTH. This function doesn't really give you "antialiasing" (although the documentation claims so). It's something a bit different (and IMO useless). If you want proper antialiasing, you need to create a multisampled backbuffer.

See here: http://nehe.gamedev.net/lesson.asp?index=10

Another way to get real antialiasing is to render to a FBO using a multisampled render-target.

I admit, it's all more complicated then just enabling line-smoothing, but it's worth looking into all this stuff.

Jan.

schallkiste
03-26-2009, 03:18 AM
I will try it and then i let you know, how it works :)

when it works, i upload the saver for download ... when im at home :)

schallkiste
03-26-2009, 11:29 PM
The Problem is the order of paint the lines. if the first line you draw is closer then the next line, the aliasing did not work fine. but if the second line is closer to you, it works.

i have tried the multisample backbuffer ... i tried at first the sample, which is on the page. but the pc didn't show any aa? so i cancel the try.

is there in opengl an order, where you can push all the thinks you want to draw, then opengl calculates the distances in dependence to your rotation an draws in order far away to near?

Jan
03-27-2009, 03:35 AM
No, GPUs are not capable to cache and sort things for you. This is a major pain especially for proper transparency.

However antialiasing using a multisampled backbuffer does work without a proper rendering-order, ie. it does not matter in which order you render your lines.

Jan.