c++ - OpenGL/过剩 : Making the camera rotate around X axis with arrow keys?

标签 c++ opengl glut opengl-compat

我正在尝试创建 gluLookAt() 函数,以便当我按下向上和向下键时相机绕 X 轴移动

我正在尝试我在以下位置看到的方法:http://www.lighthouse3d.com/tutorials/glut-tutorial/keyboard-example-moving-around-the-world/ 但这对我不起作用。有人知道更简单的方法吗?我应该将 gluLookAt() 等放在 myDisplay() 函数中的什么位置?

#include"glut.h"
#include<cmath>
#include<iostream>
using namespace std;

float xr = 0, yr = 0; //to control the object's movement from left to right

// actual vector representing the camera's direction
float lx = 0.0f, lz = -1.0f;
// XZ position of the camera
float x = 0.0f, z = 5.0f;

GLfloat angle = 0.0f;
int refreshmill = 1;

void timer(int value) { //to control the rotation of the object
    glutPostRedisplay();
    glutTimerFunc(refreshmill, timer, 0);
}

void myDisplay(void) {
    //Circle One
    float theta;
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1, 0, 0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glPushMatrix();
    glBegin(GL_POLYGON);
    for (int x = 0; x < 360; x++) {
        theta = x * 3.142 / 180;
        glVertex2f(150 * cos(theta)+xr,150 * sin(theta)+yr);
    }
    glEnd();
    glPopMatrix();

    //Circle Two
    float theta2;
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glPushMatrix();
    glTranslatef(0.5f, 0.0f, 0.0f); // rotation
    glRotatef(angle, 0.0f, 0.0f, -0.5f); // rotation
    glBegin(GL_POLYGON);
    glColor3f(0, 0, 1);
    for (int x = 0; x < 360; x++) {
        theta2 = x * 3.142 / 180;
        glVertex2f(150 + 15 * cos(theta2) + xr, 15 * sin(theta2) + yr);
    }
    glutSwapBuffers();
    angle += 0.2; // rotation
    glEnd();
    glPopMatrix();

    //Draw Star
    glColor3ub(119, 193, 15);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glPushMatrix();
    glBegin(GL_POLYGON);
    glVertex2d(15+xr, 60+yr);
    glVertex2d(75+xr, 75+yr); //right peak
    glVertex2d(15+xr, 90+yr);
    glVertex2d(0+xr, 150+yr); //Up-peak Changed
    glVertex2d(-15+xr, 90+yr);
    glVertex2d(-75+xr,75+yr);
    glVertex2d(-15+xr, 60+yr);
    glVertex2d(0+xr,0+yr);
    glEnd();
    glPopMatrix();
    glFlush();
    glutPostRedisplay();
    glutSwapBuffers();

}

void renderScene(void) {

    // Clear Color and Depth Buffers

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Reset transformations
    glLoadIdentity();
    // Set the camera
    gluLookAt(x, 1.0f, z,
        x + lx, 1.0f, z + lz,
        0.0f, 1.0f, 0.0f);

    // Draw ground
    glColor3f(0.9f, 0.9f, 0.9f);
    glBegin(GL_QUADS);
    glVertex3f(-100.0f, 0.0f, -100.0f);
    glVertex3f(-100.0f, 0.0f, 100.0f);
    glVertex3f(100.0f, 0.0f, 100.0f);
    glVertex3f(100.0f, 0.0f, -100.0f);
    glEnd();

    myDisplay();

    glutSwapBuffers();
}

//Move to left or right
void keyboard(int key, int x, int y) {

    float fraction = 0.1f;

    switch (key) {
    case GLUT_KEY_RIGHT:
        xr++;
        cout << x << endl;
        glutPostRedisplay();
        break;

    case GLUT_KEY_LEFT:
        xr--;
        cout << x << endl;
        glutPostRedisplay();
        break;

    case GLUT_KEY_UP:
        angle -= 0.01f;
        lx = sin(angle);
        lz = -cos(angle);
        break;

    case GLUT_KEY_DOWN:
        angle += 0.01f;
        lx = sin(angle);
        lz = -cos(angle);
        break;
    }
}

void init() {
    glClearColor(0, 0, 0, 1);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-250, 250, -250, 250); //IMPORTANT- Define from negative to positive
    glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char** argv) {
    // init GLUT and create window
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("Homework: Circle");
    // register callbacks
    glutDisplayFunc(myDisplay);
    glutDisplayFunc(renderScene);
    glutIdleFunc(renderScene);
    glutTimerFunc(0,timer,0);
    glutSpecialFunc(keyboard);
    // OpenGL init
    init();
    // enter GLUT event processing cycle
    glutMainLoop();
}

最佳答案

首先应该只有1个显示回调函数:

int main(int argc, char** argv) {

    // [...]

    // glutDisplayFunc(myDisplay); <----- DELETE!!!
    glutDisplayFunc(renderScene);

    // glutIdleFunc(renderScene);  <----- DELETE!!!

    // [...]
}

设置一个具有延伸的近平面和远平面的正投影。如果对象绕 X 轴旋转,它将占用 3 个维度的空间:

void init() {
    glClearColor(0, 0, 0, 1);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-250, 250, -250, 250, -250, 250); // <----
    glMatrixMode(GL_MODELVIEW);
}

添加一个变量anglaX,该变量在键盘事件中更改:

float angleX = 0.0f;
void keyboard(int key, int x, int y) {

    switch (key) {
        case GLUT_KEY_RIGHT: xr++; break;
        case GLUT_KEY_LEFT:  xr--; break;
        case GLUT_KEY_UP:    angleX -= 1.0f; break;
        case GLUT_KEY_DOWN:  angleX += 1.0f; break;
    }
}

设置 View 后旋转模型:

gluLookAt(x, 0.0f, z, x, 0.0f, z-1.0f, 0.0f, 1.0f, 0.0f);
glRotatef(angleX, 1, 0, 0);

不要对 glutSwapBuffers()glFlush()glutPostRedisplay() 进行任何调用,除非在 末尾>渲染场景:

void timer(int value) { //to control the rotation of the object
    // glutPostRedisplay(); <--- DELETE
    glutTimerFunc(refreshmill, timer, 0);
}
void myDisplay(void) {
    //Circle One
    float theta;
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1, 0, 0);

    glPushMatrix();
    glBegin(GL_POLYGON);
    for (int x = 0; x < 360; x++) {
        theta = x * 3.142 / 180;
        glVertex2f(150 * cos(theta)+xr,150 * sin(theta)+yr);
    }
    glEnd();
    glPopMatrix();

    //Circle Two
    float theta2;

    glPushMatrix();
    glTranslatef(0.5f, 0.0f, 0.0f); // rotation
    glRotatef(angle, 0.0f, 0.0f, -0.5f); // rotation
    glBegin(GL_POLYGON);
    glColor3f(0, 0, 1);
    for (int x = 0; x < 360; x++) {
        theta2 = x * 3.142 / 180;
        glVertex2f(150 + 15 * cos(theta2) + xr, 15 * sin(theta2) + yr);
    }

    angle += 0.2; // rotation
    glEnd();
    glPopMatrix();

    //Draw Star
    glColor3ub(119, 193, 15);

    glPushMatrix();
    glBegin(GL_POLYGON);
    glVertex2d(15+xr, 60+yr);
    glVertex2d(75+xr, 75+yr); //right peak
    glVertex2d(15+xr, 90+yr);
    glVertex2d(0+xr, 150+yr); //Up-peak Changed
    glVertex2d(-15+xr, 90+yr);
    glVertex2d(-75+xr,75+yr);
    glVertex2d(-15+xr, 60+yr);
    glVertex2d(0+xr,0+yr);
    glEnd();
    glPopMatrix();
}
void renderScene(void) {

    // Clear Color and Depth Buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Reset transformations
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // Set the camera
    gluLookAt(x, 0.0f, z, x, 0.0f, z-1.0f, 0.0f, 1.0f, 0.0f);
    glRotatef(angleX, 1, 0, 0);

    // Draw ground
    glColor3f(0.9f, 0.9f, 0.9f);
    glBegin(GL_QUADS);
    glVertex3f(-100.0f, 0.0f, -100.0f);
    glVertex3f(-100.0f, 0.0f, 100.0f);
    glVertex3f(100.0f, 0.0f, 100.0f);
    glVertex3f(100.0f, 0.0f, -100.0f);
    glEnd();

    myDisplay();

    glFlush();
    glutPostRedisplay();
    glutSwapBuffers();
}

此外,我建议使用双缓冲:

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

关于c++ - OpenGL/过剩 : Making the camera rotate around X axis with arrow keys?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55820387/

相关文章:

c++ - GLUT + OpenGL 多重采样抗锯齿 (MSAA)

c++ - DLL和绘图功能消失

python - 是什么导致我的 Python C 扩展崩溃?

c++ - 避免错误的用户输入(当要求的是整数时为字符串)

c++ - ffmpeg 视频输出不饱和

c++ - Qt - Glut32 库

c++ - 从指针更改数组中的值?

opengl - GLSL:当前绘制调用中的图元数量

java - 在 Eclipse 中,在哪里可以找到自动包含所选静态导入的选项?

c++ - 显示列表中的GLU二次曲面?