• Advertisement

Archived

This topic is now archived and is closed to further replies.

OH Woe is Me!! Picking not working!

This topic is 5885 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I''ve been trying to get picking working for my tile based level editor without any luck. my format for a map is simply setup as:
  
void Create_Map()
{
  int x, z;
  for (z=0;z<size;z++)
  for (x=0;x<size;x++)
  {
    Map.tile[x][z].x = (float)x-(size/2);
    Map.tile[x][z].y = -1.0f;
    Map.tile[x][z].z = (float)z-(size/2);
  }
}
  
and I draw my map like so:
  
void Draw_Map()
{
  int x, z;
  for (z=0;z<size;z++)
  for (x=0;x<size;x++)
  {
    glBegin(GL_QUADS);
    glVertex3f(Map.tile[x][z].x, Map.tile[x][z].y, Map.tile[x][z].z);
    glVertex3f(Map.tile[x+1][z].x, Map.tile[x+1][z].y, Map.tile[x+1][z].z);
    glVertex3f(Map.tile[x+1][z+1].x, Map.tile[x+1][z+1].y, Map.tile[x+1][z+1].z);
    glVertex3f(Map.tile[x][z+1].x, Map.tile[x][z+1].y, Map.tile[x][z+1].z);
    glEnd();
  }
}
  
it goes pretty much something like that. Now how would I go about picking one of the polygons in the map so that i could change it texture/properties and so on? I''ve tried following Lesson 33 on NeHe''s website, and also the OpenGL SuperBible 2nd Edition with no luck. Please help. Thanks, Scott Email Website
"If you try and don''t succeed, destroy all evidence that you tried."

Share this post


Link to post
Share on other sites
Advertisement
Ok, I'm not an expert on picking, but I'll try to explain it.

        
void Draw_Map()
{
int x, z;
for (z=0;z<size;z++)
{
for (x=0;x<size;x++)
{
// Add this line

glLoadName(z+x*size);

glBegin(GL_QUADS);
glVertex3f(Map.tile[x][z].x, Map.tile[x][z].y, Map.tile[x][z].z);
glVertex3f(Map.tile[x+1][z].x, Map.tile[x+1][z].y, Map.tile[x+1][z].z);
glVertex3f(Map.tile[x+1][z+1].x, Map.tile[x+1][z+1].y, Map.tile[x+1][z+1].z);
glVertex3f(Map.tile[x][z+1].x, Map.tile[x][z+1].y, Map.tile[x][z+1].z);
glEnd();
}
}
}


That's only required for the actual naming of objects.

Note that OpenGL is limited to 64 objects when picking,
so size can't be larger than 8

You'll also need a function that tests to see if a tile is
selected. This function takes 2 parameters, the mouse x and y values
  

bool PickTile(int x, int y)
{
// check to see if x,y are even pointing at the map

// if not it's faster if we don't even test them for picking


GLuint Buffer[512];
GLint Hits;
GLint Viewport[4];

glGetIntegerv(GL_VIEWPORT, Viewport);
glSelectBuffer(512, Buffer);

glRenderMode(GL_SELECT);
glInitNames();
glPushName(0);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Note change y to Window.Height-y if picking seems upside down

gluPickMatrix(x, y, 1.0f, 1.0f, Viewport);

gluPerspective(45.0f, f_Ratio, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);

// Note that this does NOT actually draw the map, you must

//do that elsewhere, because we are in GL_SELECT mode

Draw_Map();

glMatrixMode(GL_MODELVIEW);
Hits = glRenderMode(GL_RENDER); // Returns how many objects

// are drawn at [x,y]


if (Hits > 0)
{
GLuint Picked = Buffer[3];
GLuint Depth = Buffer[1];

for (int i = 1; i < Hits; i++)
{
// Check if this hit is over the previous one

if ((Buffer[i*4+1] < Depth))
{
Picked = Buffer[i*4+3];
Depth = Buffer[i*4+1];
}
}
}
else
{
// Nothing was picked

return false;
}

// Ok, now you can get the value of which tile was selected like this

int MapX = Picked % size; // size is same as in Draw_Map()

int MapY = Picked / size;

return true;
}


This isn't perfect, and can be improved greatly. If you don't understand something, I'll try to help, but I may not be able to beyond this, because picking isn't my forte.

Feel free to email me.

Edited by - Lord Karnus on September 19, 2001 12:45:33 AM

Edited by - Lord Karnus on September 19, 2001 12:46:28 AM

Share this post


Link to post
Share on other sites
question before i try it out. if opengl only supports up to 64 names, can i possibly test say 32x32 tiles?

crap. does this mean i have to do some frustum checking to see which poly's are in the viewport than check them??? still, that doesn't let me have a lot of tile on screen at once.

btw: i'm tired, and probably missing a simple answer

thanks,
Scott

Email
Website

"If you try and don't succeed, destroy all evidence that you tried."

Edited by - wojtos on September 19, 2001 12:58:45 AM

Share this post


Link to post
Share on other sites
The tile based editor could be done without using selection, if it's 2d, top down. First, determine your tile dimensions in pixels. Now, you can decide which tile the mouse cursor is over like this:

    
// TileSizeX = tile width in pixels

// TileSizeY = tile height in pixels

// if the screen can scroll right or down

// ScrollX = number of pixels screen is scrolled right

// ScrollY = number of pixels screen is scrolled down


int TileX = (int)((MouseX + ScrollX) / TileSizeX);
int TileY = (int)((MouseY + ScrollY) / TileSizeY);


This may be wrong, as I, too, am quite tired

Edited by - Lord Karnus on September 20, 2001 5:44:05 AM

Share this post


Link to post
Share on other sites
unfortunatly, the tile edtior is in full 3d. because the tiles that i will change will be things such as 3d walls. it''s in isometric, but is in full 3d at the same time.

Email
Website

"If you try and don''t succeed, destroy all evidence that you tried."

Share this post


Link to post
Share on other sites
If it''d the editor, make the edit mode 2D and view it in 3D.

Alex Broadwin
A-Tronic Software & Design
-----
"if you fail in life, you were destined to fail. If you suceed in life, call me."
"The answer is out there."
"Please help, I''m using Windows!"

Share this post


Link to post
Share on other sites
Yeah, that''d probably easier. However, have any of you played Dungeon Keeper? and if so, you know how it''s possible to select was to be destroyed? well, that''s basically what i wanted my editor to behave as.

but, i may just make it 2D.

thanks,
Scott

Email
Website

"If you try and don''t succeed, destroy all evidence that you tried."

Share this post


Link to post
Share on other sites
Perhaps you should look into ray casting.
I don''t know how to do it, but I know how it works.
Shoot an invisible ray from the camera and the first thing hit is the target.
Look at any FPS source at the weapon firing code, see if that helps.

Feel free to email me.

Share this post


Link to post
Share on other sites
OpenGL isn''t limited to 64 objects when picking - it is limited to the name stack going over 64 objects deep. I''m using it for my tile based game (with far more than 64 tiles available) and it works fine. As long as you don''t go insane with the heirarchy it should be alright.

-Scott-

Share this post


Link to post
Share on other sites
I once again must agree with Lord Karnus on this issue. Ray casting has got to be the easiest way of detecting if an object has been selected by the mouse in my opinion. I use it in my games all the time, and its great.

Look into it.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Hi wojtos,

I wish I could help you out, sorry. I was wondering though, I noticed your map structure and was wondering how you got x, y and z to be a member of ''tile'' when ''tile'' is a member of ''map''?

-Echo

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
There is a pretty simple way that I know of... just use colors. Draw each polygon to an off-screen buffer as a different color.. then when you click, get the color of the off-screen buffer, and then you know which polygon it was.. that''s a simple way.. uses a bit more GPU power.. but, is reliable (provided you''re working in true color, or seperate your colors a little bit) and pretty quick since you aren''t texturing or lighting or anything.

Billy

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Oh, and i''m assuming his structures are setup like so:

struct Vertex_S
{
float x,y,z;
};

struct Map_S
{
Vertex_S Tiles[32][32]; //Or whatever number
};

Map_S Map;


Billy

Share this post


Link to post
Share on other sites
Billy,

Thanks for the response. I tried it out and sure enough it worked. That was really beginning to puzzle me

Thanks again.

-Echo

God did not create the world
in 7 days; he messed around for 6 days and then pulled an all-nighter.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Heh, no problem.

Billy

Share this post


Link to post
Share on other sites

  • Advertisement