Я почти закончил с программой, что я просил сделать, но я застрял в очень простой логической проблеме и что:OpenGL/GLUT Простой вопрос в принятии поездку, чтобы быть гладкой
Увеличение скорость езды плавно левым щелчком мыши, пока мы не достигнем максимальной скорости, или щелчок правой кнопкой мыши не попал.
Плавно уменьшайте скорость езды путем правого клика мыши, пока мы не достигнем нулевой скорости, или щелкнули левой кнопкой мыши.
Я использую сигнал и скорости int
переменных для достижения своей цели, но у меня есть 2 проблемы:
- Если я использую
Sleep()
функцию, чтобы замедлить конечное время цикла программа просто зависает и ничего не работает , Если я не использую функциюSleep()
, просто движение становится мгновенным прыжком, и нет никакого чувства, что что-либо движется вообще. - Кроме того, правый и левый щелчок мыши работает только 2 раза, и просто после этого они не работают.
Любой намек было бы здорово.
Мой коммутатор заявление для мыши:
switch (button) {
case GLUT_LEFT_BUTTON:
signal = 0;
smothIncrease();
break;
case GLUT_MIDDLE_BUTTON:
case GLUT_RIGHT_BUTTON:
signal = 1;
smothDecrease();
break;
default:
break;
}
Вспомогательные функции:
void smothIncrease(){
while (true){
if (signal == 0){
if (speed == 15)
break;
angle++;
speed++;
Sleep(15);
glutPostRedisplay();
}
else if (signal == 1)
break;
}
}
void smothDecrease(){
while (true){
if (signal == 1){
if (speed == 0)
break;
angle--;
speed--;
Sleep(15);
glutPostRedisplay();
}
else if (signal == 0)
break;
}
}
Вот полный исходный код:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define PI 3.14159265
static GLfloat lpos[] = { 0.0, 5.0, 4.0, 1.0 };
static GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
static GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
static GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };
static GLfloat lightgreen[] = { 0.5, 1.0, 0.5, 1.0 };
static float alpha = 0.0;
static float beta = PI/6.0;
static float zoom = 25.0;
static bool lightSource = true;
float numberOfTriangles = 1;
static GLdouble cpos[3];
static double fenceHeight = -0.5;
static int angle = 0;
static int angle__IN_RANGE = 0.0;
static double radian__IN_RANGE = 0.0;
static int arrayOfAnglesInRange[181];
static int id = 0;
static int speed = 0;
static int signal = 0;
void writemessage()
{
}
void processAngle(){
angle__IN_RANGE = arrayOfAnglesInRange[abs(angle) % 181];
}
void setRadian_IN_RANGE(){
radian__IN_RANGE = ((float)angle__IN_RANGE/180) * PI;
}
void fillArray(){
int j = -45;
for (int i = 0; i < 181; i++)
{
if (i < 90)
arrayOfAnglesInRange[i] = j++;
else
arrayOfAnglesInRange[i] = j--;
}
//for (int i = 0; i < 182; i++)
//{
// printf("%d\n", arrayOfAnglesInRange[i]);
//}
}
void keepTrackOfID(){
int tempAngle = angle;
//if (id % 4 == 0)
// angle += 0;
//else if (id % 4 == 1)
// angle += 60;
//else if (id % 4 == 2)
// angle += 120;
//else if (id % 4 == 3)
// angle += 180;
//if (id % 4 == 0)
// angle += 0;
//else if (id % 4 == 1)
// angle += 45;
//else if (id % 4 == 2)
// angle += 90;
//else if (id % 4 == 3)
// angle += 135;
if (id % 4 == 0)
angle += 0;
else if (id % 4 == 1)
angle += 30;
else if (id % 4 == 2)
angle += 60;
else if (id % 4 == 3)
angle += 90;
processAngle();
setRadian_IN_RANGE();
angle = tempAngle;
}
void smothIncrease(){
while (true){
if (signal == 0){
if (speed == 15)
break;
angle++;
speed++;
Sleep(15);
glutPostRedisplay();
}
else if (signal == 1)
break;
}
}
void smothDecrease(){
while (true){
if (signal == 1){
if (speed == 0)
break;
angle--;
speed--;
Sleep(15);
glutPostRedisplay();
}
else if (signal == 0)
break;
}
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLfloat)w/(GLfloat)h, 0.01, 50.0);
glMatrixMode(GL_MODELVIEW);
}
void DrawSticksArroundYard(){
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, black);
GLUquadricObj *quadObj;
// Right-Line
glPushMatrix();
glTranslatef(6.8, 1.0 + fenceHeight, -7.0);
quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.1, 0.1, 14.0, 10, 10);
glPopMatrix();
// Left-Line
glPushMatrix();
glTranslatef(-6.8, 1.0 + fenceHeight, -7.0);
quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.1, 0.1, 14.0, 10, 10);
glPopMatrix();
// Back-Line
glPushMatrix();
glTranslatef(-6.8, 1.0 + fenceHeight, -7.0);
glRotatef(90, 0, 1, 0);
quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.1, 0.1, 13.7, 10, 10);
glRotatef(-90, 0, 1, 0);
glPopMatrix();
// Front-Line
glPushMatrix();
glTranslatef(6.8, 1.0 + fenceHeight, 7.0);
glRotatef(-90, 0, 1, 0);
quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.1, 0.1, 13.7, 10, 10);
glRotatef(90, 0, 1, 0);
glPopMatrix();
// Pin-Front-Right
glPushMatrix();
glTranslatef(6.8, 0, 7.0);
glRotatef(-90, 1, 0, 0);
quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.2, 0.1, 1.3 + fenceHeight, 10, 10);
glRotatef(90, 1, 0, 0);
glPopMatrix();
// Pin-Front-Left
glPushMatrix();
glTranslatef(-6.8, 0, 7.0);
glRotatef(-90, 1, 0, 0);
quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.2, 0.1, 1.3 + fenceHeight, 10, 10);
glRotatef(90, 1, 0, 0);
glPopMatrix();
// Pin-Back-Left
glPushMatrix();
glTranslatef(-6.8, 0, -7.0);
glRotatef(-90, 1, 0, 0);
quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.2, 0.1, 1.3 + fenceHeight, 10, 10);
glRotatef(90, 1, 0, 0);
glPopMatrix();
// Pin-Back-Right
glPushMatrix();
glTranslatef(6.8, 0, -7.0);
glRotatef(-90, 1, 0, 0);
quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.2, 0.1, 1.3 + fenceHeight, 10, 10);
glRotatef(90, 1, 0, 0);
glPopMatrix();
// Pin-Back-Center
glPushMatrix();
glTranslatef(0, 0, -7.0);
glRotatef(-90, 1, 0, 0);
quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.2, 0.1, 1.3 + fenceHeight, 10, 10);
glRotatef(90, 1, 0, 0);
glPopMatrix();
// Pin-Front-Center
glPushMatrix();
glTranslatef(0, 0, 7.0);
glRotatef(-90, 1, 0, 0);
quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.2, 0.1, 1.3 + fenceHeight, 10, 10);
glRotatef(90, 1, 0, 0);
glPopMatrix();
// Pin-Right-Center
glPushMatrix();
glTranslatef(6.8, 0, 0);
glRotatef(-90, 1, 0, 0);
quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.2, 0.1, 1.3 + fenceHeight, 10, 10);
glRotatef(90, 1, 0, 0);
glPopMatrix();
// Pin-Left-Center
glPushMatrix();
glTranslatef(-6.8, 0, 0);
glRotatef(-90, 1, 0, 0);
quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.2, 0.1, 1.3 + fenceHeight, 10, 10);
glRotatef(90, 1, 0, 0);
glPopMatrix();
}
void DrawYardFloor(){
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, lightgreen);
glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, lightgreen);
glBegin(GL_POLYGON);
glNormal3f(0, 1, 0);
glVertex3f(-7.3, -0.005, -7.3);
glVertex3f(-7.3, -0.005, 7.3);
glVertex3f(7.3, -0.005, 7.3);
glVertex3f(7.3, -0.005, -7.3);
glEnd();
}
void DrawCenterPin(){
glRotatef(-90, 1, 0, 0);
GLUquadricObj *quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.2, 0.2, 7, 10, 10);
glRotatef(90, 1, 0, 0);
}
void DrawBase(){
glRotatef(-90, 1, 0, 0);
GLUquadricObj *quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.5, 0.1, 2, 10, 10);
glRotatef(90, 1, 0, 0);
}
void DrawTop(){
glPushMatrix();
glTranslatef(0, 7, 0);
glRotatef(-90, 1, 0, 0);
GLUquadricObj *quadObj = gluNewQuadric();
gluCylinder(quadObj, 0.2, 0.0, 0.5, 10, 10);
glRotatef(90, 1, 0, 0);
glPopMatrix();
}
void DrawHorizontalStick(){
glLineWidth(15);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINES);
glVertex3f(0.0, 7.0, 0.0);
glVertex3f(4.0 * cos(radian__IN_RANGE), 7.0 + 3.0 * sin(radian__IN_RANGE), 0.0);
glEnd();
}
void DrawVerticalStick(){
glLineWidth(5);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINES);
glVertex3f(4.0 * cos(radian__IN_RANGE), 7.0 + 3.0 * sin(radian__IN_RANGE), 0.0);
glVertex3f(4.0 * cos(radian__IN_RANGE), 7.0 + 3.0 * sin(radian__IN_RANGE) - 1, 0.0);
glEnd();
}
void DrawCabin(){
// Back
glNormal3f(0.0, 0.0, -1.0);
glBegin(GL_POLYGON);
glVertex3f(0, 0, -1);
glVertex3f(0, 1, -1);
glVertex3f(2, 1, -1);
glVertex3f(2, 0, -1);
glEnd();
glNormal3f(0.0, 0.0, -1.0);
glBegin(GL_POLYGON);
glVertex3f(0, 1.7, -1);
glVertex3f(0, 2, -1);
glVertex3f(2, 2, -1);
glVertex3f(2, 1.7, -1);
glEnd();
glNormal3f(0.0, 0.0, -1.0);
glBegin(GL_POLYGON);
glVertex3f(0, 1, -1);
glVertex3f(0, 1.7, -1);
glVertex3f(0.2, 1.7, -1);
glVertex3f(0.2, 1, -1);
glEnd();
glNormal3f(0.0, 0.0, -1.0);
glBegin(GL_POLYGON);
glVertex3f(1.8, 1, -1);
glVertex3f(1.8, 1.7, -1);
glVertex3f(2, 1.7, -1);
glVertex3f(2, 1, -1);
glEnd();
// Front
glNormal3f(0.0, 0.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f(2, 0, 1);
glVertex3f(2, 1, 1);
glVertex3f(0, 1, 1);
glVertex3f(0, 0, 1);
glEnd();
glNormal3f(0.0, 0.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f(2, 1.7, 1);
glVertex3f(2, 2, 1);
glVertex3f(0, 2, 1);
glVertex3f(0, 1.7, 1);
glEnd();
glNormal3f(0.0, 0.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f(0.2, 1, 1);
glVertex3f(0.2, 1.7, 1);
glVertex3f(0, 1.7, 1);
glVertex3f(0, 1, 1);
glEnd();
glNormal3f(0.0, 0.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f(2, 1, 1);
glVertex3f(2, 1.7, 1);
glVertex3f(1.8, 1.7, 1);
glVertex3f(1.8, 1, 1);
glEnd();
// Floor
glNormal3f(0.0, -1.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(2, 0, -1);
glVertex3f(2, 0, 1);
glVertex3f(0, 0, 1);
glVertex3f(0, 0, -1);
glEnd();
// Top
glNormal3f(0.0, 1.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(2, 2, 1);
glVertex3f(2, 2, -1);
glVertex3f(0, 2, -1);
glVertex3f(0, 2, 1);
glEnd();
// Right
glNormal3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(2, 0, -1);
glVertex3f(2, 1, -1);
glVertex3f(2, 1, 1);
glVertex3f(2, 0, 1);
glEnd();
glNormal3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(2, 1.7, -1);
glVertex3f(2, 2, -1);
glVertex3f(2, 2, 1);
glVertex3f(2, 1.7, 1);
glEnd();
glNormal3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(2, 1, -1);
glVertex3f(2, 1.7, -1);
glVertex3f(2, 1.7, -0.8);
glVertex3f(2, 1, -0.8);
glEnd();
glNormal3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(2, 1, 0.8);
glVertex3f(2, 1.7, 0.8);
glVertex3f(2, 1.7, 1);
glVertex3f(2, 1, 1);
glEnd();
// Left
glNormal3f(-1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(0, 0, -1);
glVertex3f(0, 0, 1);
glVertex3f(0, 1, 1);
glVertex3f(0, 1, -1);
glEnd();
glNormal3f(-1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(0, 1.7, -1);
glVertex3f(0, 1.7, 1);
glVertex3f(0, 2, 1);
glVertex3f(0, 2, -1);
glEnd();
glNormal3f(-1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(0, 1, -1);
glVertex3f(0, 1, -0.8);
glVertex3f(0, 1.7, -0.8);
glVertex3f(0, 1.7, -1);
glEnd();
glNormal3f(-1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(0, 1, 0.8);
glVertex3f(0, 1, 1);
glVertex3f(0, 1.7, 1);
glVertex3f(0, 1.7, 0.8);
glEnd();
}
void darwCabin__FINAL(){
glPushMatrix();
glTranslatef(4.0 * cos(radian__IN_RANGE), 7.0 + 3.0 * sin(radian__IN_RANGE) - 3, 0.0);
glRotatef(angle, 0, 1, 0);
glPushMatrix();
glTranslatef(-1, 0, 0);
DrawCabin();
glPopMatrix();
glRotatef(-angle, 0, 1, 0);
glPopMatrix();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 64);
cpos[0] = zoom * cos(beta) * sin(alpha);
cpos[1] = zoom * sin(beta);
cpos[2] = zoom * cos(beta) * cos(alpha);
gluLookAt(cpos[0], cpos[1], cpos[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
if (lightSource == true){
glLightfv(GL_LIGHT0, GL_POSITION, lpos);
glMaterialfv(GL_FRONT, GL_EMISSION, white);
glPushMatrix();
glTranslatef(lpos[0], lpos[1], lpos[2]);
glutSolidSphere(0.1, 10, 8);
glPopMatrix();
glMaterialfv(GL_FRONT, GL_EMISSION, black);
}
DrawYardFloor();
DrawSticksArroundYard();
DrawCenterPin();
DrawBase();
DrawTop();
glRotatef(angle, 0, 1, 0);
for (int i = 0; i < 4; i++){
glPushMatrix();
glRotatef(i * 360/4, 0, 1, 0);
keepTrackOfID();
DrawHorizontalStick();
DrawVerticalStick();
darwCabin__FINAL();
id++;
glPopMatrix();
}
glRotatef(-angle, 0, 1, 0);
glutSwapBuffers();
glFlush();
}
void keyboard(unsigned char key, int x, int y)
{
static int polygonmode[2];
switch (key) {
case 27:
exit(0);
break;
case 'x':
if (lightSource == true)
lpos[0] = lpos[0] + 0.2;
glutPostRedisplay();
break;
case 'X':
if (lightSource == true)
lpos[0] = lpos[0] - 0.2;
glutPostRedisplay();
break;
case 'y':
if (lightSource == true)
lpos[1] = lpos[1] + 0.2;
glutPostRedisplay();
break;
case 'Y':
if (lightSource == true)
lpos[1] = lpos[1] - 0.2;
glutPostRedisplay();
break;
case 'z':
if (lightSource == true)
lpos[2] = lpos[2] + 0.2;
glutPostRedisplay();
break;
case 'Z':
if (lightSource == true)
lpos[2] = lpos[2] - 0.2;
glutPostRedisplay();
break;
case '+':
if (zoom != 1.5)zoom = zoom - 0.5;
glutPostRedisplay();
break;
case '-':
if (zoom != 30)zoom = zoom + 0.5;
glutPostRedisplay();
break;
case '0':
if (lightSource == true){
glDisable(GL_LIGHT0);
lightSource = false;
}
else{
glEnable(GL_LIGHT0);
lightSource = true;
}
glutPostRedisplay();
break;
case 'e':
if (fenceHeight < 2)
fenceHeight += 0.5;
glutPostRedisplay();
break;
case 'd':
if (fenceHeight > -0.5)
fenceHeight -= 0.5;
glutPostRedisplay();
break;
case 'w':
glGetIntegerv(GL_POLYGON_MODE, polygonmode);
if (polygonmode[0] == GL_FILL)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glutPostRedisplay();
break;
case 'n':
angle++;
processAngle();
setRadian_IN_RANGE();
glutPostRedisplay();
break;
case 'm':
angle--;
processAngle();
setRadian_IN_RANGE();
glutPostRedisplay();
break;
default:
break;
}
}
void mouse(int button, int state, int x, int y)
{
switch (button) {
case GLUT_LEFT_BUTTON:
signal = 0;
smothIncrease();
break;
case GLUT_MIDDLE_BUTTON:
case GLUT_RIGHT_BUTTON:
signal = 1;
smothDecrease();
break;
default:
break;
}
}
void specialkey(GLint key, int x, int y)
{
switch (key) {
case GLUT_KEY_RIGHT:
alpha = alpha + PI/180;
if (alpha > 2 * PI) alpha = alpha - 2 * PI;
glutPostRedisplay();
break;
case GLUT_KEY_LEFT:
alpha = alpha - PI/180;
if (alpha < 0) alpha = alpha + 2 * PI;
glutPostRedisplay();
break;
case GLUT_KEY_UP:
if (beta < 0.45*PI) beta = beta + PI/180;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN:
if (beta > -0.05*PI) beta = beta - PI/180;
glutPostRedisplay();
break;
default:
break;
}
}
int main(int argc, char** argv)
{
writemessage();
fillArray();
processAngle();
setRadian_IN_RANGE();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1200, 800);
glutInitWindowPosition(0, 0);
glutCreateWindow(argv[0]);
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
/* initially GL_FILL mode (default), later GL_LINE to show wireframe */
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_LIGHTING);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glEnable(GL_LIGHT0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 5.0, 10.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutSpecialFunc(specialkey);
glutMainLoop();
return 0;
}
'GLUTPostRedisplay' НЕ отображать кадр. Все, что он делает, уведомляет GLUT, чтобы отобразить ваш кадр в следующем GLUT-mainloop. Избавьтесь от петель в ваших функциях 'smoothXXX' и каждый раз меняйте скорость на единицу. – user1781290