|
memcmp for comparing colors |
A. van Patmos
Member #15,349
October 2013
|
I want to compare colors of pixels (using 5.0.10) and after reading this: if(!memcmp(al_map_rgb(255,0,255), al_get_pixel(magenta, ev.mouse.x + cameraX, ev.mouse.y + cameraY), sizeof(ALLEGRO_COLOR); where magenta = al_load_bitmap("pictures/01magnta.bmp"); and al_lock_bitmap(magenta, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY)
The compiler says: error: incompatible type for argument 1 of 'memcmp'. The same for argument 2. ALLEGRO_COLOR var1 = al_map_rgb(255,0,255) ALLEGRO_COLOR var2 = al_get_pixel(magenta, ev.mouse.x + cameraX, ev.mouse.y + cameraY) To get this to work? Or am I doing something wrong in the memcmp statement? |
RPG Hacker
Member #12,492
January 2011
|
AFAIK, memcmp takes pointers to memory. So yeah, you should delcare var1 and var2 like that and then pass &var1 and &var2 to memcmp.
|
A. van Patmos
Member #15,349
October 2013
|
I misunderstood memcmp and maybe I still do. 1ALLEGRO_BITMAP *veld_magenta;
2veld_magenta = al_load_bitmap("m01mgnta.bmp");
3...
4ALLEGRO_COLOR magenta = al_map_rgb(255,0,255);
5ALLEGRO_COLOR proefpixel;
6...
7al_lock_bitmap(veld_magenta, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY);
8...
9if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN && ev.mouse.button & 1)
10 {
11 proefpixel = al_get_pixel(veld_magenta, ev.mouse.x + cameraX, ev.mouse.y + cameraY);
12 if(memcmp(&magenta, &proefpixel, sizeof(ALLEGRO_COLOR)) != 0)
13 {
14 if(muisinterval < 30)
15 {
16 if(COMANDO)
17 Com.dubbelklik = true; //printf("Dubbelklik %i \n", muisinterval);
18 }
19 else
20 if(COMANDO)
21 Com.dubbelklik = false; //printf("Enkel %i \n", muisinterval);
22 muisinterval = 0;
23
24 if(COMANDO)
25 {
26 Com.doelX = ev.mouse.x + cameraX;
27 Com.doelY = ev.mouse.y + cameraY;
28 ...
29 }
30 }
31 }
Now mr. Com moves to any place no matter where I click. That's the same as not having the condition at all. Setting the memcmp condition to '== 0' makes him not move at all. (I'd expect him to move to magenta areas but he is consistent.) |
bamccaig
Member #7,536
July 2006
|
This could be a good place to abstract the comparison into a separate function (assuming the overhead of another call isn't significant, and usually it wouldn't be). That way you can focus on testing just the comparison in isolation and once you're confident that it works properly you can focus on the rest. That also simplifies this function that is actually doing things with the comparison. int al_ext_color_equals( ALLEGRO_COLOR * lhs, ALLEGRO_COLOR * rhs) { int ret = memcmp(lhs, rhs, sizeof(ALLEGRO_COLOR)); return ret == 0; } Note also ML's advice in the referenced thread. Since the color values are floats you may want to approximate the comparison to catch almost equal colors. That's up to you. I'm not sure how likely (or unlikely) it is for color attributes to be approximately different using whatever technique that they're being created from... When you're trying to debug code it's important to isolate the specific part that's buggy. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Mark Oates
Member #1,146
March 2001
|
I use a threshold of 0.0001 in the header file. -- |
SiegeLord
Member #7,827
October 2006
|
1 / 256.0 should be enough for any practical purpose. "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
A. van Patmos
Member #15,349
October 2013
|
Thanks so far people. Should the following: ALLEGRO_COLOR magenta = al_map_rgb(255,0,255); printf("%f\n", magenta.r);printf("%f\n", magenta.g);printf("%f\n", magenta.b);
not print this? |
Bruce Pascoe
Member #15,931
April 2015
|
Mark: C++ supports default parameter values? When did this happen, or was that always supported?
|
Mark Oates
Member #1,146
March 2001
|
Yea, it's always been there (if I understand you correctly). You have to put the default parameters in the declaration (not the definition), which means they usually go in the header file. It kinda sucks because I like the idea that your default params are controlled by the library and not the header files. Also, parameters with defaults have to be the last ones in the list (You can't add parameters without defaults after). C++ doesn't support named parameters, unfortunately. -- |
Elias
Member #358
May 2000
|
SiegeLord said: 1 / 256.0 should be enough for any practical purpose. Well, with texture compression and whatnot, a color component may get shrunk down to less than that, then when you read back from the texture you lose a lot of precision. For example if all that happens is that the texture internally uses 16-bit 565 format, then a color of 255, 255, 255 will end up as 31, 63, 31 and read back as: 248, 252, 248. So the difference is 255/256 - 248/256 = 7 / 256. So I'd say 7 / 256.0 is a safer bet than 1 / 256.0 if you happen to read colors back from a texture or the screen. -- |
|