PDA

View Full Version : Draw a checker floor



krekas
03-04-2008, 01:33 PM
Hi all!
Can anyone help me and explain me how can I draw one of those tipical checker floors but without textures...just with two simple colors.

Thanks for your time!
krekas

ZbuffeR
03-04-2008, 02:35 PM
Think in small steps. First decompose your problem. Then implement each part. Debug until end result is ok for you.

I will do the steps for you:


for x in each line
for y in each row
if modulo2(x+y)==0 then
glColor(white)
else
glColor(black)
endif
drawQuadAt(x,y)
endfor
endfor


Ok so now which part poses a problem ?

krekas
03-05-2008, 06:23 AM
Hi XbufferR,

Thanks for your code snippet it make more sense to approch the problem like that. My question is: What do you mean by each line? Do you mean each pixel line on the scene? Because I would like to be also able to define the size of each square.

Thanks

-NiCo-
03-05-2008, 06:44 AM
That depends on how you set up your projection matrix. Here's some code that'll help:



unsigned int GridSizeX = 16;
unsigned int GridSizeY = 16;
unsigned int SizeX = 8;
unsigned int SizeY = 8;

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,GridSizeX*SizeX,0,GridSizeY*SizeY,-1.0,1.0);

glBegin(GL_QUADS);
for (unsigned int x =0;x<GridSizeX;++x)
for (unsigned int y =0;y<GridSizeY;++y)
{
if ((x+y)&amp;0x00000001) //modulo 2
glColor3f(1.0f,1.0f,1.0f); //white
else
glColor3f(0.0f,0.0f,0.0f); //black

glVertex2f( x*SizeX, y*SizeY);
glVertex2f((x+1)*SizeX, y*SizeY);
glVertex2f((x+1)*SizeX,(y+1)*SizeY);
glVertex2f( x*SizeX,(y+1)*SizeY);

}
glEnd();

krekas
03-05-2008, 07:48 AM
Hi Nico,
That is a a very good example of the implementation of the pseudo code above, thanks! Now 2 questions:

1- The presented result is a 2D floor over the x an y plans. If I want the floor to go in depth, isn't it enought to change glOrtho() to glFrustum()? Because if I do it, the quad vanishes..

2- If I do the floor in depth, should I use glVertex3f() with an also increasing z value? or is is enough to have glVertex2f() with glFrustum()?

Thanks

-NiCo-
03-05-2008, 08:07 AM
Orthographic projections (glOrtho,gluOrtho...) are completely different from perspective projections (gluPerspective,glFrustum,...). You'll probably find lots of info on them on google & wikipedia.

Here's some code for a perspective camera with a vertical opening angle of 'fov'. You can adapt the 'depth' value in the range [near,far]



float fov = 90.0f;
float near = 1.0f;
float far = 1000.0f;

float depth = 10.0f;

unsigned int GridSizeX = 16;
unsigned int GridSizeY = 16;
unsigned int SizeX = 8;
unsigned int SizeY = 8;


glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( GridSizeX*SizeX/2 , GridSizeY*SizeY/2 , 0.0f ,
GridSizeX*SizeX/2 , GridSizeY*SizeY/2 , 1.0f ,
0.0f , 1.0f , 0.0f);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov,window_width/window_height,near,far);

glBegin(GL_QUADS);
for (unsigned int x =0;x<GridSizeX;++x)
for (unsigned int y =0;y<GridSizeY;++y)
{
if ((x+y)&amp;0x00000001) //modulo 2
glColor3f(1.0f,1.0f,1.0f); //white
else
glColor3f(0.0f,0.0f,0.0f); //black

glVertex3f( x*SizeX, y*SizeY,depth);
glVertex3f((x+1)*SizeX, y*SizeY,depth);
glVertex3f((x+1)*SizeX,(y+1)*SizeY,depth);
glVertex3f( x*SizeX,(y+1)*SizeY,depth);

}
glEnd();

krekas
03-05-2008, 08:54 AM
Yes you are right. I have been reading about then on google. That is why I made the previous questions =) Thanks again for your snippet, it become clear what I have been reading. I was stuck with glFrustum() rather that looking to gluLookAt() and glPerspective().

If I would like to make the floor visible from the bottom of the scene until some horizontal line with perspective ( example (http://www.tjhsst.edu/~dhyatt/superap/samplex.jpg)). Is it better to rotate the quads, or keep changing the depth parameter when the quads are built?

krekas
03-05-2008, 08:59 AM
Sorry I didn't told you before. The aim all this is to be able to draw the floor in perspective, to then analyse aliasing.

-NiCo-
03-05-2008, 09:07 AM
Well, for a large checkerboard like that it would be very inefficient to draw every quad. You'd be better off with a single quad and a 2x2 texture:

|black white|
|white black|

Then draw a quad with the full size of your checkerboard and apply a texture with the texture wrapping mode set to GL_REPEAT.

e.g.


glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);
glVertex2f(0.0f,0.0f);
glTexCoord2f(GridSizeX*2.0f,0.0f);
glVertex2f(1.0f,0.0f);
glTexCoord2f(GridSizeX*2.0f,GridSizeY*2.0f);
glVertex2f(1.0f,1.0f);
glTexCoord2f(0.0f,GridSizeY*2.0f);
glVertex2f(0.0f,1.0f);
glEnd();


When using a texture like this, you may also want to take a look at mipmapping and anisotropic filtering to reduce aliasing artifacts.

krekas
03-05-2008, 09:13 AM
I understand. As far as I read, most of floors are made with textures. I didn't want to make like that because if the aim is to analaze aliasing/anti-aliasing then I'm already combining the problem not only just to simple primitives but also with textures. Which when concerning anti-aliasing the have different techniques. Do you think it makes different concerning aliasing if the floor is just quads of is it is textured?

-NiCo-
03-05-2008, 09:26 AM
If you're not using a multisample buffer. The result of using many quads will be the same as the textured one with the filtering mode set to GL_NEAREST (I think :-s ). If you're using mipmapped/anisotropic filtering (GL_LINEAR_MIPMAP_LINEAR,etc..) you will get some texture anti-aliasing when writing to a non-multisampled buffer. This will be different from rendering many quads on a multisampled buffer because than the anti-aliasing will depend on the sampling pattern used by the multisample buffer.

krekas
03-05-2008, 10:54 AM
The result of using many quads will be the same as the textured one with the filtering mode set to GL_NEAREST (I think :-s )
Then to know it I have to try it! As you recommended I implemented it with a texture. But my problem with that is that I have this blury image in the bottom. And that does not happen with only quads :S
http://franciscoespana.ac.webfusion.co.uk/misc/a.jpg

Why is that? can it has something to do with the code of creating a texture? I'm using this snippet:


make_texture(int maxs, int maxt)
{
int s, t;
static GLfloat *texture;

texture = (GLfloat *) malloc(maxs * maxt * sizeof(GLfloat));
for (t = 0; t < maxt; t++) {
for (s = 0; s < maxs; s++) {
texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1);
}
}
return texture;
}


Then I just use it:



GLfloat *tex;
tex = make_texture(TEXDIM, TEXDIM);
glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex);


Then I belive I still have an illumination issue to solve because my white, is not white at all..bu that is anothe issue :D

-NiCo-
03-05-2008, 11:03 AM
Did you set both the magnification and minification filters to GL_NEAREST?

krekas
03-05-2008, 11:23 AM
Of course!! I had then set to GL_LINEAR :p Now it looks like I expected! It is really nice to be so well helped in my first post and topic of the forum. Thanks.

I have also to analyze the existent anti-aliasing opengl methods. I read about those but I only found that opengl does not have any method in with you can specify for example supersampling parameters. I found glHint() but it looked a little bit "poor" in the sense that the parameters are things such DONT_CARE, NICEST.. I then also found another method which uses the accumulation buffer, altough I didn't read enough to understand how it work I belive is works by "shaking" the scene and render it at teh same time. Are there any known and/or standard methods do anti-aliasing in opengl?

-NiCo-
03-05-2008, 12:58 PM
You are very welcome :)

You can use multisampling. Personally, I usually create a framebuffer object (http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt) with a multisample renderbuffer (http://www.opengl.org/registry/specs/EXT/framebuffer_multisample.txt) attached with the number of samples I need. After I've rendered to it, I blit (http://www.opengl.org/registry/specs/EXT/framebuffer_blit.txt) the result to my single sample window provided framebuffer.

You have some control on the number of samples per pixel (not all sample counts are supported) but AFAIK you don't have any control over the sampling pattern that is used. Additionally, NV hardware also provides multisample coverage (http://www.opengl.org/registry/specs/NV/framebuffer_multisample_coverage.txt) modes.

krekas
03-05-2008, 03:51 PM
Interesting! but before moving into that. If I increase the size of the texture in order to cover the quad with a smaller pattern work for ...512x512, 1024x1024 but than when I increase it to 2049x2049 the quad is not textured. Is there any reason for that?

-NiCo-
03-05-2008, 04:00 PM
The MAX_TEXTURE_SIZE of your hardware is probably limited to 2048x2048. If you want a smaller pattern, why don't you increase the texture coordinates? that way more wrappings will occur.

krekas
03-05-2008, 05:16 PM
I tought about it! but quit that idea because I thought that textures coordinates where always in the range (0,0) to (1,1). (another think I learned today!).

Concerning the anti-aliasing. I will try to implement multisampling . Your personal approach seams a little too complex for me =P All I want is to try to implement simple adaptive and non-adaptive anti-alising and I belive I can get that with multiSampling, right? Because by the name it looks some kind of related with super sampling!