Я сейчас в курсе C++ и узнаю о переключателях, которые наш инструктор хотел, чтобы мы отредактировали тело некоторого кода openGL 3D. Мы должны были поменять его с одного, а затем на переключатель. Я сделал это, но теперь мой код не будет работать. Вот код:
void key(unsigned char k, int x, int y)
{
k = tolower(k);
switch(k)
{
case 'a' : b_animate = !b_animate;
if (b_animate)
{
glutTimerFunc(33, myTimer, 1);
}
break;
case 'h' : b_showHints = !b_showHints;
glutPostRedisplay();
break;
case 'f' : toggleFullScreen();
break;
case 'o' : gi_projection_type = ORTHO_3D;
myReshape(g_windowWidth, g_windowHeight);
glutPostRedisplay();
break;
case 'p' : gi_projection_type = PERSPECTIVE;
myReshape(g_windowWidth, g_windowHeight);
glutPostRedisplay();
break;
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
case '8' :
case '9' : double alpha = (k - '0') * 0.1;
if (alpha == 0)
alpha = 1.0;
setAlphaChannel(alpha);
glutPostRedisplay();
break;
case '+' : per_angle += 2;
myReshape(g_windowWidth, g_windowHeight);
glutPostRedisplay();
break;
case '-' : per_angle -= 2;
myReshape(g_windowWidth, g_windowHeight);
glutPostRedisplay();
break;
case 'm' : printModelViewMatrix();
break;
case 'w' : b_wireFrame = !b_wireFrame;
glutPostRedisplay();
break;
case 'q' : b_useOpenGLtransform = !b_useOpenGLtransform;
glutPostRedisplay();
break;
case 'n' : g_model = (g_model + 1)%8;
glutPostRedisplay();
break;
case 't' : b_texture = !b_texture;
glutPostRedisplay();
break;
case 'l' : b_lighting = !b_lighting;
glutPostRedisplay();
break;
}
Вот исходный код (извините, он немного испортился, я копировал и вставлял в комментарий):
if(k == 'a'){
b_animate = !b_animate;
if (b_animate){
glutTimerFunc(33, myTimer, 1);
}else if (k == 'h'){
b_showHints = !b_showHints;
glutPostRedisplay();
}else if(k == 'f'){
toggleFullScreen();
}else if (k == 'o'){
gi_projection_type = ORTHO_3D;
myReshape(g_windowWidth, g_windowHeight);
glutPostRedisplay();
}else if (k == 'p'){
gi_projection_type = PERSPECTIVE;
myReshape(g_windowWidth, g_windowHeight);
glutPostRedisplay();
}else if (k >= '0' && k <= '9'){
double alpha = (k - '0') * 0.1;
if (alpha == 0)
alpha = 1.0;
setAlphaChannel(alpha);
glutPostRedisplay();
}else if (k == '+'){
per_angle += 2;
myReshape(g_windowWidth, g_windowHeight);
glutPostRedisplay();
}else if (k == '-'){
per_angle -= 2;
myReshape(g_windowWidth, g_windowHeight);
glutPostRedisplay();
}else if (k == 'm'){
printModelViewMatrix();
}else if (k == 'w'){
b_wireFrame = !b_wireFrame;
glutPostRedisplay();
}else if (k == 'q'){
b_useOpenGLtransform = !b_useOpenGLtransform;
glutPostRedisplay();
}else if (k == 'n'){
g_model = (g_model + 1)%8;
glutPostRedisplay();
}else if (k == 't'){
b_texture = !b_texture;
glutPostRedisplay();
}else if (k == 'l'){
b_lighting = !b_lighting;
glutPostRedisplay();
}
}
}
Оператор if then else все еще будет работать. Ошибки, которые я получаю с помощью переключателя: синтаксическая ошибка перед "двойным"
'alpha' uneclared (первое использование в этой функции)
Вы не можете объявлять переменные внутри оператора switch, если вы не помещаете их в блок (surround с {}
):
switch(k)
{
case 'a' : b_animate = !b_animate;
if (b_animate)
{
glutTimerFunc(33, myTimer, 1);
}
break;
case 'h' : b_showHints = !b_showHints;
glutPostRedisplay();
break;
case 'f' : toggleFullScreen();
break;
case 'o' : gi_projection_type = ORTHO_3D;
myReshape(g_windowWidth, g_windowHeight);
glutPostRedisplay();
break;
case 'p' : gi_projection_type = PERSPECTIVE;
myReshape(g_windowWidth, g_windowHeight);
glutPostRedisplay();
break;
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
case '8' :
case '9' : { // Note: begin of block
double alpha = (k - '0') * 0.1;
if (alpha == 0)
alpha = 1.0;
setAlphaChannel(alpha);
glutPostRedisplay();
break;
} // Note: end of block
case '+' : per_angle += 2;
myReshape(g_windowWidth, g_windowHeight);
glutPostRedisplay();
break;
case '-' : per_angle -= 2;
myReshape(g_windowWidth, g_windowHeight);
glutPostRedisplay();
break;
case 'm' : printModelViewMatrix();
break;
case 'w' : b_wireFrame = !b_wireFrame;
glutPostRedisplay();
break;
case 'q' : b_useOpenGLtransform = !b_useOpenGLtransform;
glutPostRedisplay();
break;
case 'n' : g_model = (g_model + 1)%8;
glutPostRedisplay();
break;
case 't' : b_texture = !b_texture;
glutPostRedisplay();
break;
case 'l' : b_lighting = !b_lighting;
glutPostRedisplay();
break;
}
Альтернативно, объявите alpha
перед оператором switch.
Вы стали жертвой дизайна "все в одном". Функционирование тела - это нечитаемый беспорядок.
Конечно, вы можете копаться в этом беспорядке столько, сколько необходимо, пока вы его не исправите. Но лучше подумайте об общем дизайне. Разделите его на меньшие функции, по одному для каждой клавиши:
case 'a' : OnKeyA(); break;
case 'h' : OnKeyH(x, y, z); break
case 'f' : OnKeyF(x); break;
....
void OnKeyA()
{
b_animate = !b_animate;
if (b_animate)
{
glutTimerFunc(33, myTimer, 1);
}
}
Разве это не намного чище? Заявления о делах становятся однострочными, и вся логика переходит к функциям. Вы никогда не заблудитесь в фигурных скобках.
Расскажите своему преподавателю о " Разделении проблем " и " Принципе единой ответственности ", он будет впечатлен =)
Счастливое кодирование!
Всякий раз, когда вам нужно объявлять переменные внутри футляра, поместите его между фигурными скобками.
case '9' : {
double alpha = (k - '0') * 0.1;
if (alpha == 0)
alpha = 1.0;
setAlphaChannel(alpha);
glutPostRedisplay();
break;
}
вы должны обернуть обработчики case в {} like
case '9' :
{
double alpha = (k - '0') * 0.1;
if (alpha == 0)
alpha = 1.0;
setAlphaChannel(alpha);
glutPostRedisplay();
break;
}
потому что можно объявлять новые переменные только внутри области внутри конструкции коммутационного шкафа
Вам нужно добавить область для double
:
case '9' : {
double alpha = (k - '0') * 0.1;
if (alpha == 0)
alpha = 1.0;
setAlphaChannel(alpha);
glutPostRedisplay();
}
break;
и вам нужно добавить
case '0':
перед списком! (Вы случайно имели только '1'
до '9'
)
double alpha
перед оператором switch. См. Stackoverflow.com/questions/1231198/…