使用 GLUT 从键盘和形状的 increase/decrease 边获取输入

Take inputs from keyboard and increase/decrease sides of a shape using GLUT

从键盘输入,例如“+”或“-”,increase/decrease 相应地输入。例如,如果当前显示的是一个三角形,如果我按“+”,它应该会变成一个矩形等。我该如何实现?

static void DisplayShape(void)
{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3d(1,0.1,0.6);

    glBegin(GL_POINTS);

    for(int i=0;i<n;++i) // n - sides count
    {
    glVertex2f(); // the n-sided shape is to be drawn here
    }
    glEnd();


    glutSwapBuffers();
}

static void key(unsigned char key, int x, int y)
{
    switch (key)
    {
        case 27 :
        case 'q': // quit
            exit(0);
            break;

        case '+': // increase sides count
            n++;
            break;

        case '-': // decrease sides count
            if (n > 3) // cannot be less than 3
            {
                n--;
            }
            break;
    }

    glutPostRedisplay();
}

static void idle(void)
{
    glutPostRedisplay();
}

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitWindowSize(640,480);
    glutInitWindowPosition(10,10);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

    glutCreateWindow("GLUT Shapes");

    glutDisplayFunc(DisplayShape);
    glutKeyboardFunc(key);
    glutIdleFunc(idle);

    glutMainLoop();

    return EXIT_SUCCESS;
}

围绕一个圆分布 N 个点。计算从圆心到点的向量之间的角度 (360°/N)。使用他们的 Polar Coordinates:

计算点数
const float x0 = 0.0f;
const float y0 = 0.0f;
const float sideLen = 0.5;
float dist = sideLen / 2.0f / sin(M_PI * 2.0f / n / 2.0f);
float startAngle = -M_PI * (n - 2) / 2 / n;
        
glBegin(GL_LINE_LOOP);

for (int i = 0; i < n; ++i) // n - sides count
{
    float sideAngle = M_PI * 2.0 * i / n + startAngle;
    float x = x0 + dist * cos(sideAngle);
    float y = y0 + dist * sin(sideAngle);
    glVertex2f(x, y);
}
glEnd();

完整示例:

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/freeglut.h>
#define _USE_MATH_DEFINES
#include <math.h>

int n = 3;

static void DisplayShape(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3d(1, 0.1, 0.6);

    const float x0 = 0.0f;
    const float y0 = 0.0f;
    const float sideLen = 0.5;
    float dist = sideLen / 2.0f / sin(M_PI * 2.0f / n / 2.0f);
    float startAngle = -M_PI * (n - 2) / 2 / n;
        
    glBegin(GL_LINE_LOOP);

    for (int i = 0; i < n; ++i) // n - sides count
    {
        float sideAngle = M_PI * 2.0 * i / n + startAngle;
        float x = x0 + dist * cos(sideAngle);
        float y = y0 + dist * sin(sideAngle);
        glVertex2f(x, y);
    }
    glEnd();

    glutSwapBuffers();
    glutPostRedisplay();
}

static void key(unsigned char key, int x, int y)
{
    switch (key)
    {
    case 27:
    case 'q': // quit
        exit(0);
        break;

    case '+': // increase sides count
        n++;
        break;

    case '-': // decrease sides count
        if (n > 3) // cannot be less than 3
            n--;
        break;
    }
    glutPostRedisplay();
}

static void reshape(int width, int height)
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    double aspect = (double)width / height;
    glOrtho(-aspect, aspect, -1.0, 1.0, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitWindowSize(640, 480);
    glutInitWindowPosition(10, 10);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

    glutCreateWindow("GLUT Shapes");

    glutReshapeFunc(reshape);
    glutDisplayFunc(DisplayShape);
    glutKeyboardFunc(key);

    glutMainLoop();

    return EXIT_SUCCESS;
}