How to detect Command/alt/control/fn keys in GLUT - macos

I'm detecting key pressing and have some problem with the detection with fn(function), ctrl(control), alt and fn(function).
I can detect space bar, enter, ESC, letters, numbers and the cursors. But i can't detect the special keys I tell before. Both method doesn't show anything on screen when I press these keys.
Method to detect normal keys
void KeyboardFunc(unsigned char key, int x, int y)
{
int numeros;
Key[key] = true;
cout << "-----------------" << endl;
cout << "PULSE " << (int) key << endl;
cout << "-----------------" << endl;
if(key >= 48 && key < 58)
{
numeros = key;
key = 'a';
}
switch ( key )
{
case ' ': // Space bar
cout << "Barra Espaciadora pulsada." << endl;
break;
case 13: // #13 es Enter
cout << "Enter pulsada." << endl;
break;
case 27: // "27" is the Escape key
cout << "Tecla ESC pulsada." << endl;
exit(1);
case 'a': // Teclado numérico.
cout << "Número pulsado: " << numeros - 48 << endl;
key = numeros;
}
}
Method to detect special keys:
void SpecialFunc(int key, int x, int y)
{
Arrow[key] = true;
cout << "-----------------" << endl;
cout << "ESPECIAL PULSADO: " << (int) key << endl;
cout << "-----------------" << endl;
switch ( key )
{
case GLUT_KEY_UP: // #73 es cursor arriba
cout << "Cursor ARRIBA pulsada." << endl;
break;
case GLUT_KEY_DOWN: // #81 es cursor abajo
cout << "Cursor ABAJO pulsada." << endl;
break;
case GLUT_KEY_LEFT: // #73 es cursor izquierda
cout << "Cursor IZQUIERDA pulsada." << endl;
break;
case GLUT_KEY_RIGHT: // #81 es cursor derecha
cout << "Cursor DERECHA pulsada." << endl;
break;
case 30: // #30 es alt_a
cout << "Tecla ALT pulsada." << endl;
break;
}
}

OpenGL does not deal with user input. It's a drawing API and only covers getting points, lines and triangles into a raster pixmap buffer.
What you are using right now is GLUT, a rather simple framework for small OpenGL demos. GLUT is not part of OpenGL! If GLUT no longer meets your demands it's time to go on using a more capable framework, or doing all the windowing and input processing from scratch.

You could switch to SDL - get a source for brutalchess,
http://brutalchess.sourceforge.net/
and see how keys are handled in it. datenwolf is right, opengl has nothing to do with input ( mouse, keys, window focus etc. ). You could also try SFML, it's simpler than SDL
http://rastergrid.com/blog/downloads/mountains-demo/
SDL is more flexible than SFML, e.g. KEY_PRESS is something different than KEY_RELEASE.

Ok so this post is old I know but I just happened to find it while looking for something else.
Answering anyway since it may help other people in the future.
GLUT actually supports the events of ALT... being pressed.
GLUT_ACTIVE_SHIFT – Set if either you press the SHIFT key, or Caps Lock is on. Note that if they are both on then the constant is not set.
GLUT_ACTIVE_CTRL – Set if you press the CTRL key.
GLUT_ACTIVE_ALT – Set if you press the ALT key.
All you have to do is:
void processNormalKeys(unsigned char key, int x, int y) {
if (key == 27)
exit(0);
else if (key=='r') {
int mod = glutGetModifiers();
if (mod == GLUT_ACTIVE_ALT)
//piece of code
else if(//...)
//piece of code
}}

Related

C ++ , My for loop doesn't work when I run it on the terminal. Any ideas?

When I run it on the terminal it works fine but the loop. The for loop just doesn't do anything at all. I'm learning C++, so I don't know much.
#include <iostream>
#include <cstring>
using namespace std;
int main( int argc, char *argv[] ) {
if (argc == 2) {
cout << "The first argument is " << argv[0] << endl;
cout << "The second argument is " << argv[1] << endl;
} else if (argc > 2) {
cout << "Too many arguments" << endl;
exit(0);
} else {
cout << "Only one argument" << endl;
cout << "The argument is " << argv[0] << endl;
exit(0);
}
if (atoi(argv[1]) < 0) {
cout << "Error negative number" << endl;
exit(0);
}
// this loop does not work, everything else does.
for (int i = 1; i >= atoi(argv[1]); i++){
int count = atoi(argv[1]--);
cout << count << endl;
int sum = sum + i;
}
cout << "The sum is: " << endl;
return(0);}
I think that could be the if statements what are messing around with the loop.
I think you made mistake in the for loop.
You show use "<=" instead of ">=" in the for loop.
Hope this might helps you.
I guess your code is not reaching the for loop as you have exit() conditions on each and every condition of if. Your code only reaches the loop if you are passing 2 arguments in the terminal while you are running your code

Linear interpolation is not working as expected

I have a map that represents the values of a coefficient Y for a given range of temperatures. I'm trying to get the coeff_Y whenever the input key designTempfalls anywhere between the upper and lower limits of keys. I was able to get the three cases: a) when the value of the input designTemp is below the first key then coeff_Y is the first value, b) if the value of the input designTemp is beyond the last key then coeff_Y is the last value and c) if designTemp matches a key then the coeff_Y becomes the corresponding value. The case if the key falls anywhere within the key range is not working. The code showing the failed attempt of interpolation is shown below. Please note that I'm not a programmer, I'm a piping engineer just trying to write my own programs and trying to become proficient at coding with C++. Also, if there is any better solution please show so.
`cout << "\n Enter design temp. in degF: ";
float designTemp;
cin.clear(); cin.ignore(10000, '\n'); cin >> designTemp;
map<float, float> ferriticsteels_Y = { {900, 0.4}, {950, 0.5}, {1000, 0.7} };
if (ferriticsteels_Y.find(designTemp) != ferriticsteels_Y.end())
{
float coeff_Y = ferriticsteels_Y[designTemp];
cout << "\n Y: " << coeff_Y << endl;
}
if (designTemp < ferriticsteels_Y.begin()->first)
{
float coeff_Y = ferriticsteels_Y.begin()->second;
cout << "\n Y: " << coeff_Y << endl;
}
if (designTemp > ferriticsteels_Y.rbegin()->first)
{
float coeff_Y = ferriticsteels_Y.rbegin()->second;
cout << "\n Y: " << coeff_Y << endl;
}
auto lower = ferriticsteels_Y.lower_bound(designTemp) == ferriticsteels_Y.begin() ? ferriticsteels_Y.begin() : --(ferriticsteels_Y.lower_bound(designTemp));
auto upper = ferriticsteels_Y.upper_bound(designTemp);
float coeff_Y = lower->second + (upper->second - lower->second) * float(designTemp - lower->first)/fabs(upper->first - lower->first);
time_t rawtime_end;
struct tm * timeinfo_end;
time(&rawtime_end);
timeinfo_end = localtime(&rawtime_end);
cout << "\n" << asctime(timeinfo_end);
cout << "\nEnter any character and hit enter to exit: ";
char ans;
//cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); cin >> ans;...giving error at 'max()'
cin.clear(); cin.ignore(10000, '\n'); cin >> ans;
return 0;}`
It works. I just was making stupid mistake. It only required to revise the nesting of the if-statements and to add a cout for looking the interpolated value at the last else. Below is the code which works as expected:
#include "../../std_lib_facilities.h"
#include <Windows.h>
#include <map>
int main()
{
SetConsoleTitle(TEXT("PipeTran™_v0.1"));
system("CLS");
system("color F1");
time_t rawtime_start;
struct tm * timeinfo_start;
time(&rawtime_start);
timeinfo_start = localtime(&rawtime_start);
printf(asctime(timeinfo_start));
cout << "\n Enter design temp. in degF: ";
float designTemp;
cin >> designTemp;
map<float, float> ferriticsteels_Y = { { 900, 0.4 },{ 950, 0.5 },{ 1000, 0.7 } };
if (ferriticsteels_Y.find(designTemp) != ferriticsteels_Y.end()) {
float coeff_Y = ferriticsteels_Y[designTemp];
cout << "\n Y: " << coeff_Y << endl;
}
else if (designTemp < ferriticsteels_Y.begin()->first) {
float coeff_Y = ferriticsteels_Y.begin()->second;
cout << "\n Y: " << coeff_Y << endl;
}
else if (designTemp > ferriticsteels_Y.rbegin()->first) {
float coeff_Y = ferriticsteels_Y.rbegin()->second;
cout << "\n Y: " << coeff_Y << endl;
}
else {
auto lower = ferriticsteels_Y.lower_bound(designTemp) == ferriticsteels_Y.begin() ? ferriticsteels_Y.begin() : --(ferriticsteels_Y.lower_bound(designTemp));
auto upper = ferriticsteels_Y.upper_bound(designTemp);
float coeff_Y = lower->second + (upper->second - lower->second) * float(designTemp - lower->first) / fabs(upper->first - lower->first);
cout << "\n Y: " << coeff_Y << endl;
}
time_t rawtime_end;
struct tm * timeinfo_end;
time(&rawtime_end);
timeinfo_end = localtime(&rawtime_end);
cout << "\n" << asctime(timeinfo_end);
cout << "\nEnter any character and hit enter to exit: ";
char ans;
cin.clear(); cin.ignore(10000, '\n'); cin >> ans;
return 0;
}

Efficient checking for Subset

Given two bitset objects 'B1' and 'B2' of length 'n' respectively. Whats the efficient way to say whether all the bits that are set in 'B2' are also in 'B1'?
Example:
B1 = 110111
B2_bad = 011001
B2_good = 100001
So, 'B1' and 'B2_good' is good but not 'B1' and 'B2_bad'?
Well, I guess these two following methods might help. You might need to benchmark them as which is faster.
std::bitset<6> B1 (std::string("110111"));
std::bitset<6> B2_bad (std::string("011001"));
std::bitset<6> B2_good (std::string("100001"));
//////////////One way/////////////////////////
if ( (~B1 &= (B2_bad)).any()) std::cout << "No" << std::endl;
else std::cout << "Yes" << std::endl;
if ( (~B1 &= (B2_good)).any()) std::cout << "No" << std::endl;
else std::cout << "Yes" << std::endl;
///////////////Second way//////////////////
int i =0;
for (i = 0; i < B1.size(); ++i) if (B2_bad[i] == 1 && B1[i] == 0) break;
if (i == B1.size()) std::cout << "Yes" << std::endl;
else std::cout << "No" << std::endl;
for (i = 0; i < B1.size(); ++i) if (B2_good[i] == 1 && B1[i] == 0) break;
if (i == B1.size()) std::cout << "Yes" << std::endl;
else std::cout << "No" << std::endl;`
Probably, someone more proficient than me can comment on their performance. But my best guess is first method leverages the library functions which should give the best performance , however if most of your queries would have 'Result NO' and B1-B2 will not agree on one of the earlier bits then second method might have better runtime. As, library functions involved have a worst runtime complexity of O(n).

How to use SetConsoleTextAttribute C++

I have searched countless forums and websites but I can't seem to find the answer. I'm trying to use SetConsoleTextAttribute but it only affects the text. How can I affect the whole screen like the command color 1f would? My code is:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <wincon.h>
using namespace std;
int main()
{
SetConsoleTitle("C++ CALCULATOR"); // Title of window
int x; // Decision
int a; // First Number
int b; // Second Number
int c; // Answer
HANDLE Con;
Con = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(Con, BACKGROUND_BLUE | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
cout << "CALCULATOR" << endl << endl;
cout << "1:ADDITION" << endl << "2:SUBTRACTION" << endl << "3:MULTIPLICATION";
cout << endl << "4:DIVISION" << endl << "5:EXIT" << endl;
cin >> x;
switch (x)
{
case 1: // Addition code
cout << endl << "ADDITION" << endl << "FIRST NUMBER:";
cin >> a;
cout << endl << "SECOND NUMBER:";
cin >> b;
c = a + b;
cout << endl << "ANSWER:" << c;
break;
case 2: // Subtraction code
cout << endl << "SUBTRACTION" << endl << "FIRST NUMBER:";
cin >> a;
cout << endl << "SECOND NUMBER:";
cin >> b;
c = a - b;
cout << endl << "ANSWER:" << c;
break;
case 3: // Multiplication code
cout << endl << "MULTIPLICATION" << endl << "FIRST NUMBER:";
cin >> a;
cout << endl << "SECOND NUMBER:";
cin >> b;
c = a * b;
cout << endl << "ANSWER:" << c;
break;
case 4: // Division code
cout << endl << "DIVISION" << endl << "FIRST NUMBER:";
cin >> a;
cout << endl << "SECOND NUMBER:";
cin >> b;
c = a / b;
cout << endl << "ANSWER:" << c;
break;
case 5: // Exit code
return 0;
}
}
This solution relies on these WinAPI functions and structures:
GetConsoleScreenBufferInfo to get screen dimensions
FillConsoleOutputAttribute to fill screen with an attribute
CONSOLE_SCREEN_BUFFER_INFO structure to store screen information
The code is as follows:
HANDLE hCon;
CONSOLE_SCREEN_BUFFER_INFO csbiScreenInfo;
COORD coordStart = { 0, 0 }; // Screen coordinate for upper left
DWORD dwNumWritten = 0; // Holds # of cells written to
// by FillConsoleOutputAttribute
DWORD dwScrSize;
WORD wAttributes = BACKGROUND_BLUE | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
hCon = GetStdHandle(STD_OUTPUT_HANDLE);
// Get the screen buffer information including size and position of window
if (!GetConsoleScreenBufferInfo(hCon, &csbiScreenInfo))
{
// Put error handling here
return 1;
}
// Calculate number of cells on screen from screen size
dwScrSize = csbiScreenInfo.dwMaximumWindowSize.X * csbiScreenInfo.dwMaximumWindowSize.Y;
// Fill the screen with the specified attribute
FillConsoleOutputAttribute(hCon, wAttributes, dwScrSize, coordStart, &dwNumWritten);
// Set attribute for newly written text
SetConsoleTextAttribute(hCon, wAttributes);
The inline comments should be enough to understand the basics of what is going with the supplied documentation links. We get the screen size with GetConsoleScreenBufferInfo and use that to determine the number of cells on the screen to update with a new attribute using FillConsoleOutputAttribute . We then use SetConsoleTextAttribute to ensure that all new text that gets printed matches the attribute we used to color the entire console screen.
For brevity I have left off the error check for the calls to FillConsoleOutputAttribute and SetConsoleTextAttribute. I put a stub for the error handling for GetConsoleScreenBufferInfo . I leave it as an exercise for the original poster to add appropriate error handling if they so choose.
SetConsoleTextAttribute changes the attribute for new characters that you write to the console, but doesn't affect existing contents of the console.
If you want to change the attributes for existing characters already being displayed on the console, use WriteConsoleOutputAttribute instead.

Address of an instance emplaced to std::vector is invalid

I have 2 std::vectors:
to first vector, I emplace instance
to second vector, I want to store the address of the instance just emplaced
But it does not work, i.e., the stored address differs from the emplaced instance's address.
If it matters at all, I'm on Linux and using g++ 5.1 and clang 3.6 with -std=c++11.
Here's a working example to illustrate the problem.
#include <iostream>
#include <vector>
struct Foo {
Foo(int a1, int a2) : f1(a1), f2(a2) {}
int f1;
int f2;
};
int main(int, char**) {
std::vector<Foo> vec1;
std::vector<Foo*> vec2;
int num = 10;
for (int i = 0; i < num; ++i) {
vec1.emplace_back(i, i * i);
// I want to store the address of *emplaced* instance...
vec2.push_back(&vec1.back());
}
// same
std::cout << "size 1: " << vec1.size() << std::endl;
std::cout << "size 2: " << vec2.size() << std::endl;
// same for me
std::cout << "back 1: " << &vec1.back() << std::endl;
std::cout << "back 2: " << vec2.back() << std::endl;
// typically differ ?
std::cout << "front 1: " << &vec1.front() << std::endl;
std::cout << "front 2: " << vec2.front() << std::endl;
for (int i = 0; i < num; ++i) {
std::cout << i + 1 << "th" << std::endl;
// same for last several (size % 4) for me
std::cout << "1: " << &vec1[i] << std::endl;
std::cout << "2: " << vec2[i] << std::endl;
}
}
Questions
Is it correct behavior ? I guess it's caused by storing the address of temporary instance but I want to know whether it's permitted by the standard (just curious).
If above is true, how to work around this ? I resolved this by changing first one to vector<unique_ptr<Foo>> but is there any idiomatic way ?
Two options:
1) You can simply fix your test. You just need in you test preallocate enough memory first with
vec1.reserve(10);
Well, this is implementation details for std::vector. As more and more items are added to std::vector it needs to get more space for them. And this space must be contigious. So when there is not enough space for a new element std::vector allocates a bigger block of memory, copies existing elements to it, add the new element and finally frees the block of memory that it used before. As a result addresses that you stored in vec2 might become invalid.
However, if you preallocate enough memory for 10 elements then you code is correct.
Or, since reserving memory is sort of tricky thing to do
2) use std::deque since insertion and deletion at either end of a deque never invalidates pointers or references to the rest of the elements (http://en.cppreference.com/w/cpp/container/deque) and forget about the problem with invalidated addresses. So no need to reserve memory.

Resources