• Advertisement

2D how to implement picking for irregular texture, just need scheme.

Recommended Posts

A texture rectangle, texture type is RGBA.
the alpha channel like this: (0=0,x=255)
[0][0][0][0][0][0][0]
[0][0][x][x][0][0][0]
[0][x][x][x][0][0][0]
[0][x][x][x][x][x][0]
[0][0][0][x][x][x][0]
[0][0][0][x][x][0][0]
[0][0][0][0][0][0][0]

I want a function to picking. now I have a very clumsy solutions:

//system Init.............
//..........
//pixel buffer to texture....... (texture is handle, a number.cannot get pixel matrix.)
//..........
BYTE pixel_alpha[7][7];//save alpha channel matrix
//..........
texture.draw(30,30);//draw the picture in the window    x=30 , y=30
//..........
if(picking(GetMouseX,GetMouseY))MessageBox("click!"); // picking functio
//..........

/*picking function*/
bool picking(int x,int y)
{
    int mouse_to_image_x, mouse_to_image_y;//get mouse position in the image
    mouse_to_image_x = 30 - x;
    mouse_to_image_y = 30 - y;
    if((mouse_to_image_x < 0 && mouse_to_image_x > 7) && (mouse_to_image_y < 0 && mouse_to_image_y > 7))return false;//mouse is not in the image
    for(int i = 0; i < 7 * 7; i++)
    {
        if(pixel_alpha[mouse_to_image_x][mouse_to_image_y] == 255)return true;//in the image and alpha channel is 255
    }
    return false;
}
//=============================================================================================
but......
1.an excessive amount of memory in alpha channel matrix.
2.i think efficiency is not high.
so, how to do? 
not is ray picking, What is this technology called?

Share this post


Link to post
Share on other sites
Advertisement
25 minutes ago, Scouting Ninja said:

This is confusing. What software, API or what ever are you using and what is your goal?

Any 2D graphics engine. SDL2, openframeworks(use OpenGL) ............
textures is rectangular and loading a PNG image as a texture.
this PNG is a button, maybe it's various shapes.
the mouse must click the effective alpha channel. alpha >= 100 maybe.

Share this post


Link to post
Share on other sites
17 hours ago, dream rz said:

textures is rectangular and loading a PNG image as a texture.

See this is the confusing part. OpenGL has functions for loading textures it also has functions for finding pixels in a texture.

https://open.gl/textures

https://stackoverflow.com/questions/8000921/how-to-get-color-from-the-pixel-opengl

17 hours ago, dream rz said:

this PNG is a button, maybe it's various shapes.

Do you mean that you want to extract sprites from a texture. Things like UI buttons and such:

https://stackoverflow.com/questions/9609423/applying-part-of-a-texture-sprite-sheet-texture-map-to-a-point-sprite-in-ios

To get it as various shapes like a circle you first need to use vector math to plot the points, so you get it like a UV map.

 

These topics are all very basic and can be found in many OpenGL tutorials and with simple quick searches.

Did any of this help or are you looking for something else?

Share this post


Link to post
Share on other sites
42 minutes ago, Scouting Ninja said:

See this is the confusing part. OpenGL has functions for loading textures it also has functions for finding pixels in a texture.

https://open.gl/textures

https://stackoverflow.com/questions/8000921/how-to-get-color-from-the-pixel-opengl

Do you mean that you want to extract sprites from a texture. Things like UI buttons and such:

https://stackoverflow.com/questions/9609423/applying-part-of-a-texture-sprite-sheet-texture-map-to-a-point-sprite-in-ios

To get it as various shapes like a circle you first need to use vector math to plot the points, so you get it like a UV map.

 

These topics are all very basic and can be found in many OpenGL tutorials and with simple quick searches.

Did any of this help or are you looking for something else?

Yes, as you said.
that's exactly what I mean.
but.......but.........
I want a more efficient means.
applications run faster.................
only taking small area in internal memory.......................

Because in the game, FPS is very high(60 or ????). work to every frame.

so, there may be a better solution to the problem??

Share this post


Link to post
Share on other sites
8 hours ago, dream rz said:

but.......but.........
I want a more efficient means.
applications run faster.................
only taking small area in internal memory.......................

If there was a more efficient way we would already be using it. Maybe there is but we haven't found it yet, but then asking on forums isn't going to make it appear.

 

Although there isn't a more efficient way, there are ways to improve memory; it's just not more efficient because it's going to need more calculations done; slowing down the game.

For example:

Re-using textures is more memory efficient. So changing the way the texture looks when rendered, like changing the color, saves memory; instead of loading a same texture with a new color.

Using more optimized textures. For example PNG images is often 24bit but you could use a RGB 8bit and a 1bit black and white image. But a 1bit can only store 0 and 1. So transparent or not. it can't store half transparent values.

 

There are also many other ways but these are more memory-efficient not efficient, because they will need more work or some other thing done to save memory.

The thing is that all our data types are build from 0 and 1. There really isn't much more that can be done to make it efficient. You would need to run thousands of tests to find more efficient way of using textures.

Share this post


Link to post
Share on other sites

Let's say you have a texture which is an image of a button or something - and now you want 15 buttons. And another texture - a kitten - so you have 20 "Entities".

One way to do all this is to have a struct or Entity class which has it's own bottom left x,y and top right x, y to form a bounding box, yes, a good old fashioned rectangle. Not buttons, not kittens but rectangles.

Now you would have an array or list of all such Entities, each with their own x, y locations.

So you can go through your master list which has all the Entities - if the mouse x, y is not even in the bounding box of an Entity then it can quickly and easily be eliminated. There is no point in drilling down into the details of each kitten pixel if you aren't even in the same ball park as the bound box rectangle. Right?

For these "broad phase" collision tests you can use other simple shapes as well:- like circles, spheres, cylinders or whatever. The concept is the same. 

Back in the day I was an avid arcade game player and could've sworn they were doing pixel perfect collision detection. Years later I heard the actual author say it was just a bounding box or circle test. Had me fooled.

Yes you can drill down and "sample" the RGBA of a texture but I'd get the bigger picture as described above sorted out first. 

And if you have many thousand objects then you would benefit from partitioning space. A simple Grid with Cells or Quadtree for 2D, Octree for 3D will help you reduce the master list, you'd have a sub-list which only contains Entities in that neighbourhood ...

(At any rate I would not create my own data structure containing just the alpha channel bits. That's all on the CPU with regular system memory, you'd want more OpenGL and hardware acceleration help).

 

Share this post


Link to post
Share on other sites
16 hours ago, Scouting Ninja said:

If there was a more efficient way we would already be using it. Maybe there is but we haven't found it yet, but then asking on forums isn't going to make it appear.

 

Although there isn't a more efficient way, there are ways to improve memory; it's just not more efficient because it's going to need more calculations done; slowing down the game.

For example:

Re-using textures is more memory efficient. So changing the way the texture looks when rendered, like changing the color, saves memory; instead of loading a same texture with a new color.

Using more optimized textures. For example PNG images is often 24bit but you could use a RGB 8bit and a 1bit black and white image. But a 1bit can only store 0 and 1. So transparent or not. it can't store half transparent values.

 

There are also many other ways but these are more memory-efficient not efficient, because they will need more work or some other thing done to save memory.

The thing is that all our data types are build from 0 and 1. There really isn't much more that can be done to make it efficient. You would need to run thousands of tests to find more efficient way of using textures.

There appears to be no better way.
On the basis of the theory of click detection, looking for other ways to do this.
Anyway, thank you.

Share this post


Link to post
Share on other sites
1 hour ago, AlexKay said:

Let's say you have a texture which is an image of a button or something - and now you want 15 buttons. And another texture - a kitten - so you have 20 "Entities".

One way to do all this is to have a struct or Entity class which has it's own bottom left x,y and top right x, y to form a bounding box, yes, a good old fashioned rectangle. Not buttons, not kittens but rectangles.

Now you would have an array or list of all such Entities, each with their own x, y locations.

So you can go through your master list which has all the Entities - if the mouse x, y is not even in the bounding box of an Entity then it can quickly and easily be eliminated. There is no point in drilling down into the details of each kitten pixel if you aren't even in the same ball park as the bound box rectangle. Right?

For these "broad phase" collision tests you can use other simple shapes as well:- like circles, spheres, cylinders or whatever. The concept is the same. 

Back in the day I was an avid arcade game player and could've sworn they were doing pixel perfect collision detection. Years later I heard the actual author say it was just a bounding box or circle test. Had me fooled.

Yes you can drill down and "sample" the RGBA of a texture but I'd get the bigger picture as described above sorted out first. 

And if you have many thousand objects then you would benefit from partitioning space. A simple Grid with Cells or Quadtree for 2D, Octree for 3D will help you reduce the master list, you'd have a sub-list which only contains Entities in that neighbourhood ...

(At any rate I would not create my own data structure containing just the alpha channel bits. That's all on the CPU with regular system memory, you'd want more OpenGL and hardware acceleration help).

 

Of course, I know this way. high efficiency, imprecise.

int circle_x , circle_y , circle_radius;
int mouse_x , mouse_y;

int test_x = mouse_x - circle_x;//get distance difference
int test_y = mouse_y - circle_y;

int i = sqrt(test_x * test_x + circle_y * circle_y);//get square root

if(i <= circle_radius);//mouse pointer in a circle

Share this post


Link to post
Share on other sites

 

In your first post you have this function:

/*picking function*/
bool picking(int x,int y)
{
    int mouse_to_image_x, mouse_to_image_y;//get mouse position in the image
    mouse_to_image_x = 30 - x;
    mouse_to_image_y = 30 - y;
    if((mouse_to_image_x < 0 && mouse_to_image_x > 7) && (mouse_to_image_y < 0 && mouse_to_image_y > 7))return false;//mouse is not in the image
    for(int i = 0; i < 7 * 7; i++)
    {
        if(pixel_alpha[mouse_to_image_x][mouse_to_image_y] == 255)return true;//in the image and alpha channel is 255
    }
    return false;
}

 

and this data structure

BYTE pixel_alpha[7][7];//save alpha channel matrix

 

If you have gone to the trouble to store hittable bits in your own data structure wouldn't you be better of just looking up the alpha value at a given location instead of iterating in a for loop searching for it 

// something like this?
lookup_x = mouse_click_x - location_of_object_x;
lookup_y = mouse_click_y - location_of_object_y;

if(   (lookup_x < 0 || lookup_x > 7) 
   || (lookup_y < 0 || lookup_y > 7))
{
  // WAS: OOPS had && but can't be less than 0 and greater than 7 
  // NOW: changed to ||
  return 0;//mouse is not in the image
}

hit = pixel_alpha[lookup_x][lookup_y];

return hit;

 

Say mouse_x is at 355 and object corner is at 351 you need to lookup 355-351 = 4 and a similar thing for y.

Also you are storing value 255 in a BYTE, I presume a BYTE is 8 bits, so it'll cost 8 bits for each texture bit. Wouldn't you be better off using 1 bit per bit (hope that makes sense).

Sorry I can't be more specific since I'm not sure what you're trying to do, these days I would use modern OpenGL and vector graphics and I'd render to an off-screen frame-buffer, each object in its own color with unhittable objects left as black then I'd use glGetPixels to decide what was hit. So called "Color-Based Mouse Picking" ... It requires a lot more code than this - but it gets to run on a "hardware" accelerated board so probably worth it?

Cheers.

Edited by AlexKay

Share this post


Link to post
Share on other sites

So, it is really a dilemma.
For the last few years, I was always “shape pickup”.
To tell the truth, just about enough of this.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By Manuel Berger
      Hello fellow devs!
      Once again I started working on an 2D adventure game and right now I'm doing the character-movement/animation. I'm not a big math guy and I was happy about my solution, but soon I realized that it's flawed.
      My player has 5 walking-animations, mirrored for the left side: up, upright, right, downright, down. With the atan2 function I get the angle between player and destination. To get an index from 0 to 4, I divide PI by 5 and see how many times it goes into the player-destination angle.

      In Pseudo-Code:
      angle = atan2(destination.x - player.x, destination.y - player.y) //swapped y and x to get mirrored angle around the y axis
      index = (int) (angle / (PI / 5));
      PlayAnimation(index); //0 = up, 1 = up_right, 2 = right, 3 = down_right, 4 = down

      Besides the fact that when angle is equal to PI it produces an index of 5, this works like a charm. Or at least I thought so at first. When I tested it, I realized that the up and down animation is playing more often than the others, which is pretty logical, since they have double the angle.

      What I'm trying to achieve is something like this, but with equal angles, so that up and down has the same range as all other directions.

      I can't get my head around it. Any suggestions? Is the whole approach doomed?

      Thank you in advance for any input!
       
    • By Allagia X
      An original fantasy RP game needs dedicated, self-motivated, and chill individuals! We have a story and general plot already set up, ready to be expanded upon. 

      Miasma: Twilight Decree is a 2D roleplay adventure game. It’s set in a unique fantasy world with a vast map containing continents and oceans alike. Players are given one objective: to endure the troublous environments Allagia have to offer and successfully progress through time to reach the Age of Technology. The stakes are high, and every character’s actions can alter the world – or reset everything back to the beginning ages. MTD features a blend of survival aspects, dark themes, with the ability to make a mark in the history books.

      What we're currently looking for:
       
      • Writers - Super creative individuals who have experience in lore-making, world-building, and know their way around fantasy writing. All of the general elements are here [setting, plot, etc.] and need some "fluffing out"[quest lines, clans/ factions/ families, etc.]. Bonus points to those who can whip up spells and skills.
      • Artists - Mainly those who specialize in pixelated art, or people who can make concept art [since we lack pictures]. 
      • Project Manager - Someone who is organized and can keep this project on the rails. As thorough as I am, it's difficult to cover all the bases on my own. 
      • Other Positions - Anything else to fill in the gaps. We currently use Wikidot for our wiki; someone with CSS and syntax experience to polish it up would be awesome. A musician/ composer for all things musical. Way later down the road, we'll need community managers, DMs, and the such, though it isn't necessary at the moment. 

      Other information:

      I've been working on this project since the beginning of 2017 with a group of friends. Life basically prohibited a lot of us from continuing on with it, and it went on hiatus for a while. I'm making an attempt to bring this back from the dead since plenty of time and effort went into it beforehand. It goes without saying that I also have a passion for roleplaying. 

      I cannot stress enough that anyone interested should be into fantasy settings or D&D. Otherwise, you're probably not going to have fun with helping!

      We do have a Patreon with a few supporters, and Discord. Until things really start moving, we'll be using Discord to collaborate. 

      For any questions, comments, or concerns, feel free to comment below or add me on discord @ Allagia X#9174 [best method of contact] for more info about this project.
    • By francoisdiy
      So I wrote a programming language called C-Lesh to program games for my game maker Platformisis. It is a scripting language which tiles into the JavaScript game engine via a memory mapper using memory mapped I/O. Currently, I am porting the language as a standalone interpreter to be able to run on the PC and possibly other devices excluding the phone. The interpreter is being written in C++ so for those of you who are C++ fans you can see the different components implemented. Some background of the language and how to program in C-Lesh can be found here:

      http://www.codeloader.net/readme.html
      As I program this thing I will post code from different components and explain.
    • By isu diss
      I'm trying to duplicate vertices using std::map to be used in a vertex buffer. I don't get the correct index buffer(myInds) or vertex buffer(myVerts). I can get the index array from FBX but it differs from what I get in the following std::map code. Any help is much appreciated.
      struct FBXVTX { XMFLOAT3 Position; XMFLOAT2 TextureCoord; XMFLOAT3 Normal; }; std::map< FBXVTX, int > myVertsMap; std::vector<FBXVTX> myVerts; std::vector<int> myInds; HRESULT FBXLoader::Open(HWND hWnd, char* Filename, bool UsePositionOnly) { HRESULT hr = S_OK; if (FBXM) { FBXIOS = FbxIOSettings::Create(FBXM, IOSROOT); FBXM->SetIOSettings(FBXIOS); FBXI = FbxImporter::Create(FBXM, ""); if (!(FBXI->Initialize(Filename, -1, FBXIOS))) { hr = E_FAIL; MessageBox(hWnd, (wchar_t*)FBXI->GetStatus().GetErrorString(), TEXT("ALM"), MB_OK); } FBXS = FbxScene::Create(FBXM, "REALMS"); if (!FBXS) { hr = E_FAIL; MessageBox(hWnd, TEXT("Failed to create the scene"), TEXT("ALM"), MB_OK); } if (!(FBXI->Import(FBXS))) { hr = E_FAIL; MessageBox(hWnd, TEXT("Failed to import fbx file content into the scene"), TEXT("ALM"), MB_OK); } FbxAxisSystem OurAxisSystem = FbxAxisSystem::DirectX; FbxAxisSystem SceneAxisSystem = FBXS->GetGlobalSettings().GetAxisSystem(); if(SceneAxisSystem != OurAxisSystem) { FbxAxisSystem::DirectX.ConvertScene(FBXS); } FbxSystemUnit SceneSystemUnit = FBXS->GetGlobalSettings().GetSystemUnit(); if( SceneSystemUnit.GetScaleFactor() != 1.0 ) { FbxSystemUnit::cm.ConvertScene( FBXS ); } if (FBXI) FBXI->Destroy(); FbxNode* MainNode = FBXS->GetRootNode(); int NumKids = MainNode->GetChildCount(); FbxNode* ChildNode = NULL; for (int i=0; i<NumKids; i++) { ChildNode = MainNode->GetChild(i); FbxNodeAttribute* NodeAttribute = ChildNode->GetNodeAttribute(); if (NodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh) { FbxMesh* Mesh = ChildNode->GetMesh(); if (UsePositionOnly) { NumVertices = Mesh->GetControlPointsCount();//number of vertices MyV = new XMFLOAT3[NumVertices]; for (DWORD j = 0; j < NumVertices; j++) { FbxVector4 Vertex = Mesh->GetControlPointAt(j);//Gets the control point at the specified index. MyV[j] = XMFLOAT3((float)Vertex.mData[0], (float)Vertex.mData[1], (float)Vertex.mData[2]); } NumIndices = Mesh->GetPolygonVertexCount();//number of indices MyI = (DWORD*)Mesh->GetPolygonVertices();//index array } else { FbxLayerElementArrayTemplate<FbxVector2>* uvVertices = NULL; Mesh->GetTextureUV(&uvVertices); int idx = 0; for (int i = 0; i < Mesh->GetPolygonCount(); i++)//polygon(=mostly triangle) count { for (int j = 0; j < Mesh->GetPolygonSize(i); j++)//retrieves number of vertices in a polygon { FBXVTX myVert; int p_index = 3*i+j; int t_index = Mesh->GetTextureUVIndex(i, j); FbxVector4 Vertex = Mesh->GetControlPointAt(p_index);//Gets the control point at the specified index. myVert.Position = XMFLOAT3((float)Vertex.mData[0], (float)Vertex.mData[1], (float)Vertex.mData[2]); FbxVector4 Normal; Mesh->GetPolygonVertexNormal(i, j, Normal); myVert.Normal = XMFLOAT3((float)Normal.mData[0], (float)Normal.mData[1], (float)Normal.mData[2]); FbxVector2 uv = uvVertices->GetAt(t_index); myVert.TextureCoord = XMFLOAT2((float)uv.mData[0], (float)uv.mData[1]); if ( myVertsMap.find( myVert ) != myVertsMap.end() ) myInds.push_back( myVertsMap[ myVert ]); else { myVertsMap.insert( std::pair<FBXVTX, int> (myVert, idx ) ); myVerts.push_back(myVert); myInds.push_back(idx); idx++; } } } } } } } else { hr = E_FAIL; MessageBox(hWnd, TEXT("Failed to create the FBX Manager"), TEXT("ALM"), MB_OK); } return hr; } bool operator < ( const FBXVTX &lValue, const FBXVTX &rValue) { if (lValue.Position.x != rValue.Position.x) return(lValue.Position.x < rValue.Position.x); if (lValue.Position.y != rValue.Position.y) return(lValue.Position.y < rValue.Position.y); if (lValue.Position.z != rValue.Position.z) return(lValue.Position.z < rValue.Position.z); if (lValue.TextureCoord.x != rValue.TextureCoord.x) return(lValue.TextureCoord.x < rValue.TextureCoord.x); if (lValue.TextureCoord.y != rValue.TextureCoord.y) return(lValue.TextureCoord.y < rValue.TextureCoord.y); if (lValue.Normal.x != rValue.Normal.x) return(lValue.Normal.x < rValue.Normal.x); if (lValue.Normal.y != rValue.Normal.y) return(lValue.Normal.y < rValue.Normal.y); return(lValue.Normal.z < rValue.Normal.z); }  
    • By Terry Jin
      Hi everyone! 

      I am from an indie studio that has received funding for our concept and is ready to create the next generation 2D Pokemon-inspired MMORPG called Phantasy World. This ad is for a volunteer position but hopefully will transition into something more. Our vision is to create a game that draws inspiration from the series but is dramatically different in both aesthetics and gameplay as the work would be our own.
       
      We are hoping that you can help us make this a reality and are looking for game developers familiar with the unreal engine and would be happy to work on a 2D top down game. Sprite artists are also welcome as we are in desperate need of talented artists! Join our discord and let's have a chat! https://discord.gg/hfDxwDX

      Here's some of our in game sprites for playable characters while moving around the game world! Hope to see you soon!
       


  • Advertisement