Я использую GLFW + OpenGL, чтобы попытаться создать «вращающийся куб». Хотя большая часть работает, у меня есть отсечение в дальней плоскости. Я пробовал изменять значения усеченного конуса на очень большие числа, но, похоже, это не имело никакого эффекта.

int main(void) {
    if (!glfwInit()) exit(EXIT_FAILURE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
    glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
    GLFWwindow* window = glfwCreateWindow(640, 360, "3dTest", NULL, NULL);
    if (!window) {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);   // Grey Background
    float rotqube = 0;
    while (!glfwWindowShouldClose(window)) {
        // clear color and depth buffer for new frame
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // set up camera
        glViewport(0, 0, 640, 360);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glFrustum(-100.0, 100.0, -100.0, 100.0, 100.0, -100.0);

        // position camera
        glTranslatef(0.0f, 0.0f, -2.0f);    // Translate Into The Screen 2.0 Units
        glRotatef(rotqube, 0.0f, 1.0f, 0.0f);   // Rotate The cube around the Y axis
        glRotatef(rotqube, 1.0f, 1.0f, 1.0f);

        glBegin(GL_QUADS);      // Draw The Cube Using quads
        glColor3f(0.0f, 1.0f, 0.0f);    // Color Blue
        glVertex3f(1.0f, 1.0f, -1.0f);  // Top Right Of The Quad (Top)
        glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Top)
        glVertex3f(-1.0f, 1.0f, 1.0f);  // Bottom Left Of The Quad (Top)
        glVertex3f(1.0f, 1.0f, 1.0f);   // Bottom Right Of The Quad (Top)
        ...
        glColor3f(1.0f, 0.0f, 1.0f);    // Color Violet
        glVertex3f(1.0f, 1.0f, -1.0f);  // Top Right Of The Quad (Right)
        glVertex3f(1.0f, 1.0f, 1.0f);   // Top Left Of The Quad (Right)
        glVertex3f(1.0f, -1.0f, 1.0f);  // Bottom Left Of The Quad (Right)
        glVertex3f(1.0f, -1.0f, -1.0f); // Bottom Right Of The Quad (Right)
        glEnd();            // End Drawing The Cube

        rotqube += 0.3f;

        //Swap buffer and check for events
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwDestroyWindow(window);
    glfwTerminate;
    exit(EXIT_SUCCESS);
    return 0;
}

Вот как это выглядит:

This is what it looks like

2
Andre Vallestero 2 Янв 2018 в 19:36

2 ответа

Лучший ответ

Вы вообще не используете перспективную проекцию. Ваш звонок

glFrustum(-100.0, 100.0, -100.0, 100.0, 100.0, -100.0);

Не имеет никакого эффекта , кроме установки состояния ошибки GL_INVALID_VALUE.

Как указано в спецификации OpenGL 2.0, раздел 2.11 "Координаты Преобразования »:

За

void Frustum( double l, double r, double b, double t, double n, double f );

координаты (l, b, −n)^T и (r, t, −n)^T указать точки на ближнем отсечении плоскости, которые отображаются в левом нижнем и правом верхнем углах окна, соответственно (при условии, что глаз расположен в (0, 0, 0)^T). f дает расстояние от глаза до дальней плоскости отсечения. Если либо n, либо f меньше или равно нулю , l равно r, b равно t или n равно f, ошибка {{ X12}} результаты .

Попытка установить проекцию, при которой одна из ближних или дальних плоскостей находится позади камеры, не имеет ни малейшего смысла и может привести к множеству математических странностей во время рендеринга (т.е. деление на ноль для вершин, лежащих на плоскости камеры), следовательно, это запрещено.

Поскольку эта функция не работает с ошибкой, вы используете единичную матрицу в качестве матрицы проекции и в итоге получаете ортогональную проекцию.

Теперь, написав все это, я должен сообщить вам, что все это полностью устарело. Конвейер фиксированных функций и стек матриц GL, включая такие функции, как glFrustum, glLoadIdendity, glRotate, и рендеринг в немедленном режиме с использованием glBegin / glEnd устарели и были удалены из основных профилей OpenGL почти десятилетие назад. Это действительно плохая идея - пытаться изучить этот материал в 2018 году, и я настоятельно рекомендую вам вместо этого изучить современный OpenGL.

3
derhass 2 Янв 2018 в 16:53
glFrustum(-100.0, 100.0, -100.0, 100.0, 100.0, -100.0);
                                               ^ wat

glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal):

Параметры:

  • left, right:

    Укажите координаты левой и правой вертикальных плоскостей отсечения.

  • bottom, top:

    Укажите координаты для нижней и верхней горизонтальных плоскостей отсечения.

  • nearVal, farVal:

    Укажите расстояния до ближней и дальней плоскостей отсечения глубины.
    Оба расстояния должны быть положительными.

Попробуйте что-нибудь вроде 0.1 для 100.0:

glFrustum(-100.0, 100.0, -100.0, 100.0, 0.1, 100.0);
3
genpfault 2 Янв 2018 в 16:52