why does glutMouseFunc track state but glutKeyboardFunc does not? - glut

I am working on a game using OpenGL and I noticed that I have to register a
glutMouseFunc(void (*func)(int button, int state, int x, int y))
to detect mouse presses and releases, but I have to register a
glutKeyboardFunc(void (*func)(unsigned char button, int x, int y))
and a
glutKeyboardUpFunc(void (*func)(unsigned char button, int x, int y))
(both of which I pipe to the function
handleKey(char state unsigned char button, int x, int y)
function anyway)
to do the same thing for key presses. Why doesn't glutKeyboardFunc just pass the state like glutMouseFunc does?

Related

Generating tensors with elements based on position in xtensor

I am trying to build a data structure to represent an RGB image in xtensor (a 3D matrix, with shape in the form of (WIDTH, HEIGHT, 3).
Each "pixel" contains data collected by a function of the pixel coordinates. Basically, I want to replicate what this code does in python:
image = [[cell_info(x, y) for x in range(WIDTH)]
for y in range(HEIGHT)]
where cell info returns a 3 elements list representing the color channels.
I suppose the proper way to do this should be using an xgenerator, but to be honest I cannot understand how to use that class.
I found a solution:
I changed cell_info to accept a int channel parameter, so that it returns an integer instead of an array. Then I wrote this:
class img_generator_fn {
public:
using value_type = int;
img_generator_fn(const Map *map, const Position &center, shared_ptr<const Player> player,
const unsigned int field_radius)
: m_map(map), m_center(center), m_player(player), m_translation(-(field_radius + 1)) {}
~img_generator_fn() { m_map = nullptr; }
inline auto operator()(const unsigned int x, const unsigned int y, const unsigned int channel) const {
return m_map->at(m_center + Position(x, y))->cell_info(m_player, channel);
}
template <class It> inline auto element(It, It end) const {
return m_map->at(m_center + Position(*(end - 2) + m_translation, (*(end - 3)) + m_translation))
->cell_info(m_player, *(end - 1));
}
private:
const Map *m_map;
const Position &m_center;
shared_ptr<const Player> m_player;
const unsigned int m_translation;
};
template <unsigned int field_side> auto field(const Position &center, shared_ptr<const Player> player) const {
const array<unsigned int, 3> shape = {field_side, field_side, 3};
auto gen = xt::detail::make_xgenerator(img_generator_fn(this, center, player, (field_side - 1) / 2), shape);
return xt::xtensor_fixed<int, xt::xshape<field_side, field_side, 3>>(gen);
}
Here Map represents a 2D matrix, it is the structure which contains, togheter with player, the informations I want to store in an image. The function at picks up the map cell at the specified position (the map cell will be converted into a pixel). The function field generates an image centered around center from a given Map, using an xgenerator.

How to get mouse position on mouse wheel event

Contrary to MouseMotionEvent, MouseWheelEvent does not provide the mouse location (the fields x and y are used for horizontal and vertical scrolling instead).
SDL provides SDL_GetMouseState() to retrieve the current mouse position, but it is not expressed in the same coordinate system:
SDL_Event event;
while (SDL_WaitEvent(&event)) {
switch (event.type) {
case SDL_MOUSEMOTION: {
int x, y;
SDL_GetMouseState(&x, &y);
printf("event=(%d, %d) state=(%d, %d)\n",
event.motion.x, event.motion.y, x, y);
}
}
}
When I move the mouse, it prints something like:
event=(700, 184) state=(479, 126)
event=(702, 175) state=(480, 120)
event=(706, 168) state=(485, 111)
It seems that the motion event is expressed relative to the texture or renderer (which is scaled and centered in the window) while the state is expressed relative to the window, in pixels.
Is there a way to get the current mouse state matching the position filled in mouse events?
I ended up by converting the coordinates manually:
void convert_to_renderer_coordinates(SDL_Renderer *renderer, int *x, int *y) {
SDL_Rect viewport;
float scale_x, scale_y;
SDL_RenderGetViewport(renderer, &viewport);
SDL_RenderGetScale(renderer, &scale_x, &scale_y);
*x = (int) (*x / scale_x) - viewport.x;
*y = (int) (*y / scale_y) - viewport.y;
}
I use this function to convert the mouse state coordinates:
SDL_Event event;
while (SDL_WaitEvent(&event)) {
switch (event.type) {
case SDL_MOUSEMOTION: {
int x, y;
SDL_GetMouseState(&x, &y);
convert_to_renderer_coordinates(&x, &y);
printf("event=(%d, %d) state=(%d, %d)\n",
event.motion.x, event.motion.y, x, y);
}
}
}
Now, they match:
event=(1033, 14) state=(1033, 14)
event=(1034, 13) state=(1034, 13)
event=(1034, 11) state=(1036, 10) // this is racy, state already has a new position
event=(1036, 10) state=(1036, 10)
The mouse position is captured when the wheel event is handled (instead of when it is generated), so it is racy. But I think we can't do better with the current API.

Overloading function in C++ as unsigned char and unsigned int result in ambiguous

I have to overloaded functions:
void wypisz(unsigned int32 x, int n = 1);
void wypisz(unsigned char x, int n = 1);
here is code where I rise them:
main()
{
wypisz((int32)(32), 7);
wypisz('a', 7);
return 0;
}
and when I try to compile it using G++ I get an error:
test.cpp: In function 'int main()':
test.cpp:10:21: error: call of overloaded 'wypisz(int, int)' is
ambiguous wypisz((int)(32), 7);
test.cpp:10:21: note: candidates are:
test.cpp:5:6: note: void wypisz(unsigned int, int) void wypisz(unsigned int x, int n = 1);
test.cpp:6:6: note: void wypisz(unsigned char, int) void wypisz(unsigned char x, int n = 1);
When I remove unsigned it will compile fine.
Is there a way to call this method - wha tI should change in the call statement? Unfortunatelly I can not change anything in the declaration = they must stay as they are.
The problem is that, in your function call, you are casting to an int32, which is neither an unsigned char nor an unsigned int32. In fact, it is implicitly castable to either of them (the compiler can convert it automatically). However, because it can convert it to either automatically, it doesn't know which to convert it to, and that is why the call is ambiguous.
To call the method unambiguously, just cast it to an unsigned int32:
wypisz((unsigned int32)32, 7);
Now, the compiler doesn't have to do any implicit casting, since there is an exact match. Instead, it just calls the right function.

Placing blocks with Forge Mod Loader?

How to place a block when the user right clicks with the item?
The only method I can find that would do anything is setBlockMetadataWithUpdate() but the parameters are badly explained in the javadocs.
Have you tried taking a look into the ItemBlock class? Using the onItemUse() in combination with the placeBlockAt() function or functionality?
/**
* Called to actually place the block, after the location is determined
* and all permission checks have been made.
*
* #param stack The item stack that was used to place the block. This can be changed inside the method.
* #param player The player who is placing the block. Can be null if the block is not being placed by a player.
* #param side The side the player (or machine) right-clicked on.
*/
public boolean placeBlockAt(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ, int metadata)
{
if (!world.setBlock(x, y, z, field_150939_a, metadata, 3))
{
return false;
}
if (world.getBlock(x, y, z) == field_150939_a)
{
field_150939_a.onBlockPlacedBy(world, x, y, z, player, stack);
field_150939_a.onPostBlockPlaced(world, x, y, z, metadata);
}
return true;
}

enum acting like an unsigned int in Xcode 4.6 even when enum is defined as a signed int

I have only been able to recreate this bug using xCode 4.6. Everything works as expected using Xcode 4.5
The issue is myVal has the correct bit structure to represent an int val of -1. However, it is showing a value of 4294967295 which is the value of the same bit structure if represented by an unsigned int. You'll notice that if i cast myVal to an int it will show the correct value. This is strange, because the enum should be an int to being with.
here is a screen shot showing the value of all of my variables in the debugger at the end of main. http://cl.ly/image/190s0a1P1b1t
typedef enum : int {
BTEnumValueNegOne = -1,
BTEnumValueZero = 0,
BTEnumValueOne = 1,
}BTEnumValue;
int main(int argc, const char * argv[])
{
#autoreleasepool {
//on this line of code myVal is 0
BTEnumValue myVal = BTEnumValueZero;
//we are adding -1 to the value of zero
myVal += BTEnumValueNegOne;
//at this moment myVal has the exact bit stucture
//of a signed int at -1, but it is displaying it
//as a unsigned int, so its value is 4294967295
//however, if i cast the enum (which should already
//be an int with a signing) to an int, it displays
//the correct value of -1
int myIntVal = (int)myVal;
}
return 0;
}
The new, preferred way to declare enum types is with the NS_ENUM macro as explained in this post: http://nshipster.com/ns_enum-ns_options/