Detect alpha pixels on mouse events
by Gilberto Catarino · in Torque Game Builder · 12/14/2008 (10:00 am) · 11 replies
I'm trying to detect whether i'm clicking on an area of a static Sprite (can be other type of t2delement) where the image is transparent or not, but i can't get any function to do it.
My goal is by clicking on an image drag it only if i'm clicking on an opaque area. Creating a polygon list is not acceptable because i'll be loading random images from tiled image maps.
Thanks in advance
Gilberto
My goal is by clicking on an image drag it only if i'm clicking on an opaque area. Creating a polygon list is not acceptable because i'll be loading random images from tiled image maps.
Thanks in advance
Gilberto
#2
12/30/2008 (9:52 pm)
BTW, one of the potential difficulties here is, what is the sprite is scaled smaller such that each pixel in the original sprite image does not translate to a unique pixel on the screen? Let's say the pixel you click on on the screen actually was drawn using 2 pixels from the sprite. Let's say 1 of them is transparent, the other is not. What should the function do then? So while this feature would be useful, it has its challenges in writing it.
#3
01/28/2009 (6:57 am)
I've manage to implement this feature. anyone still interested?
#4
01/28/2009 (7:32 am)
Absolutely. While my current project doesn't need it, I'd love to get this for possible future use.
#5
On file t2dImagemapDatablock.cc
On file t2dImageMapDatablock.h
02/02/2009 (10:53 am)
Ok, let's change the source for this to work.On file t2dImagemapDatablock.cc
After line 261:
mAllowUnload = Con::getBoolVariable( "$pref::T2D::imageMapAllowUnloadDefault", false );
add this:
mCreateColorMap = Con::getBoolVariable( "$pref::T2D::imageMapCreateColorDefault", false );
after line 304:
addField("preload", TypeBool, Offset(mPreload, t2dImageMapDatablock));
add this:
addField("createColorMap", TypeBool, Offset(mCreateColorMap, t2dImageMapDatablock));
after line 636:
mSrcBitmapHeight = S32( mpSrcBitmap->getHeight() );
add this:
if (mCreateColorMap){
mColorMap = new ColorI*[mSrcBitmapWidth];
//ColorI test[const mSrcBitmapWidth][const mSrcBitmapHeight];
// Creates a map with the color values of the image
for ( S32 x = 0; x < mSrcBitmapWidth; x++ ){
mColorMap[x] = new ColorI[mSrcBitmapHeight];
for (S32 y = 0; y < mSrcBitmapHeight; y++){
ColorI myColor;
mpSrcBitmap->getColor(x, y, myColor);
// gets the color value
mColorMap[x][y] = myColor;
}
}
}
after line 2253:
//-----------------------------------------------------------------------------
// Get Source Bitmap Size.
//-----------------------------------------------------------------------------
ConsoleMethod(t2dImageMapDatablock, getSrcBitmapName, const char*, 2, 2, "() Get Source Bitmap Name.n"
"@return Returns the bitmap name as a string.")
{
// Return Bitmap Name.
return object->getSrcBitmapName();
}
add this:
//-----------------------------------------------------------------------------
// Get Source Bitmap pixel information array.
//-----------------------------------------------------------------------------
ConsoleMethod(t2dImageMapDatablock, getColorAt, const char*, 4, 4, "(int x, int y) Get Source Bitmap.n"
"@return Returns the bitmap.")
{
ColorI** myColorMap = object->getColorMap();
if (!myColorMap || !object->getCreateColorMap()){
return "0";
}
// Fetch position.
S32 x = dAtoi(argv[2]);
S32 y = dAtoi(argv[3]);
if (x >= object->getSrcBitmapWidth() || y >= object->getSrcBitmapHeight()){
return "0";
}
// Create Returnable Buffer.
char* pBuffer = Con::getReturnBuffer(32);
// Format Buffer.
dSprintf(pBuffer, 32, "%d %d %d %d", myColorMap[x][y].red, myColorMap[x][y].green, myColorMap[x][y].blue, myColorMap[x][y].alpha);
return pBuffer;
}On file t2dImageMapDatablock.h
after line 225:
S32 mSrcBitmapHeight;
add this:
ColorI** mColorMap;
after line 247:
bool mAllowUnload;
add this:
bool mCreateColorMap;
after line 318:
const void bindImageMapFrame( U32 frame ) const { AssertFatal( getLockReference() > 0, "getImageMapFrameTexture() - Texture is unloaded!"); validateFrame(frame); glBindTexture( GL_TEXTURE_2D, mVecTexturePage[mVecFrameOut[frame].mTexturePage].mpPageTextureHandle->getGLName() ); };
add this:
ColorI** getColorMap( void ) const { return mColorMap; }
bool getCreateColorMap( void ) const { return mCreateColorMap; }
#6
If your image-map is a full-frame one then it'll work else it won't give you the results you expect.
If you create your "color map" based upon the dynamic texture then you'd have the ability to to select areas of frames as well!
Also, you might want to enable "color map" generation for each image-map independently otherwise the memory consumption could potentially go through the roof.
I thought I'd mention that just in case!
Melv.
02/03/2009 (6:35 am)
Cool. Just be careful here though as the source bitmap is just that, it's the source bitmap, not the dynamically created (packed) destination bitmap that's uploaded as a texture.If your image-map is a full-frame one then it'll work else it won't give you the results you expect.
If you create your "color map" based upon the dynamic texture then you'd have the ability to to select areas of frames as well!
Also, you might want to enable "color map" generation for each image-map independently otherwise the memory consumption could potentially go through the roof.
I thought I'd mention that just in case!
Melv.
#7
BTW i think if you change the bitmap dynamically u just need to call the compile function in torque to reload the colormap.
02/03/2009 (6:48 am)
Thanks for the advise. Well the colormap is only created if i say so in the constructor field (mCreateColorMap is going false if omitted), by default it's off to avoid the memory consumption. Yeah it works with full frame or cells, as a matter of fact i use it in my project with cells but that u can reach easily with torquescript.BTW i think if you change the bitmap dynamically u just need to call the compile function in torque to reload the colormap.
#8
TGB takes the source bitmap and creates another bitmap (or multiple bitmaps in texture-pages) in memory using the rules and parameters of the image-map mode. It's this (or these) bitmaps that get uploaded as textures. I never change the source bitmap at all and the "compile()" method is the entry-point of the work that does as I described.
As you already know, you can definatley use your code to refer to the original source bitmap in its coordinate space but that isn't what gets loaded to the textures according to the mode. In "Full" mode it will be but in Celled or Keyed it won't be identical, the changes of which are determined by the mode and parameters.
You code will always be able to refer to the original bitmap but apart from "Full" mode, that bitmap doesn't directly relate!
There's actually a much safer way of doing this which is to use the frame mapping structures. If you look at the method "getImageMapFramePixelArea(U32 frame)" you'll notice that it returns the pixel-area mapping from the source to the destination bitmaps. If you look at the "bindImageMapFrame" you can see how the mapping takes place. Using this you could get a "frame, x, y" position for any type of image, even linked.
Anyway, don't want to seem like I'm poo-pooing what you've done here, I just wanted offer some friendly advice! With a few constraints though your code will work fine. :)
Melv.
02/03/2009 (10:26 am)
Sorry, perhaps I didn't explain that very well. :)TGB takes the source bitmap and creates another bitmap (or multiple bitmaps in texture-pages) in memory using the rules and parameters of the image-map mode. It's this (or these) bitmaps that get uploaded as textures. I never change the source bitmap at all and the "compile()" method is the entry-point of the work that does as I described.
As you already know, you can definatley use your code to refer to the original source bitmap in its coordinate space but that isn't what gets loaded to the textures according to the mode. In "Full" mode it will be but in Celled or Keyed it won't be identical, the changes of which are determined by the mode and parameters.
You code will always be able to refer to the original bitmap but apart from "Full" mode, that bitmap doesn't directly relate!
There's actually a much safer way of doing this which is to use the frame mapping structures. If you look at the method "getImageMapFramePixelArea(U32 frame)" you'll notice that it returns the pixel-area mapping from the source to the destination bitmaps. If you look at the "bindImageMapFrame" you can see how the mapping takes place. Using this you could get a "frame, x, y" position for any type of image, even linked.
Anyway, don't want to seem like I'm poo-pooing what you've done here, I just wanted offer some friendly advice! With a few constraints though your code will work fine. :)
Melv.
#10
I'd be glad to help.
Melv.
02/03/2009 (10:40 am)
No problem. If you need any help then please drop me an email at melvm@garagegames.com.I'd be glad to help.
Melv.
#11
I am trying to implement this feature but nothing changed on my TGB when i am creating an image map.
I have build and compile the entire project T2D SDK from the "...enginecompilersVisualStudio 2005" with Visual Studio 2008.
Did I miss something ?
Can someone explain me the process to make this feature working on my TGB ?
08/25/2009 (10:43 am)
hi,I am trying to implement this feature but nothing changed on my TGB when i am creating an image map.
I have build and compile the entire project T2D SDK from the "...enginecompilersVisualStudio 2005" with Visual Studio 2008.
Did I miss something ?
Can someone explain me the process to make this feature working on my TGB ?
Torque Owner Vern Jensen
Sounds like this would be a useful new feature. In the meantime, probably something you have to modify the source to accomplish.