Модели OpenGL показывают сетчатые линии - PullRequest
2 голосов
/ 27 апреля 2011

Решена проблема с затенением;линии сетки сохраняются.См. Обновление 5

Я работаю над загрузчиком файлов .obj для OpenGL, используя Objective-C.

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

Вот мои результаты:

Sphere Blender Monkey

И вот тип эффекта, который я пытаюсь достичь:

Goal

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

Так что я понятия не имею, что я делаю здесь неправильно, извините, если вопрос кажется расплывчатым.Если потребуется дополнительная информация, я добавлю ее.

Обновление: ссылка на увеличенное изображение сломанной головы обезьяны: http://oi52.tinypic.com/2re5y69.jpg

Обновление 2: Если в процессе вычисления нормалей произошла ошибка, это то, что я делаю:

  • Создайте треугольник для каждой группы индексов.
  • Рассчитайте нормали для треугольника и сохраните его в векторе.
  • Убедитесь, что вектор нормализован с помощью следующей функции

:

static inline void normalizeVector(Vector3f *vector) {
    GLfloat vecMag = VectorMagnitude(*vector);
    if (vecMag == 0.0) {
        vector->x /= 1.0; 
        vector->y /= 0.0;
        vector->z /= 0.0;
    }
    vector->x /= vecMag;
    vector->y /= vecMag;
    vector->z /= vecMag;
}

Обновление 3: вот код, который я использую для создания нормали:

- (void)calculateNormals {
    for (int i = 0; i < numOfIndices; i += 3) {      
        Triangle triangle;
        triangle.v1.x = modelData.vertices[modelData.indices[i]*3];
        triangle.v1.y = modelData.vertices[modelData.indices[i]*3+1];
        triangle.v1.z = modelData.vertices[modelData.indices[i]*3+2];

        triangle.v2.x = modelData.vertices[modelData.indices[i+1]*3];
        triangle.v2.y = modelData.vertices[modelData.indices[i+1]*3+1];
        triangle.v2.z = modelData.vertices[modelData.indices[i+1]*3+2];

        triangle.v3.x = modelData.vertices[modelData.indices[i+2]*3];
        triangle.v3.y = modelData.vertices[modelData.indices[i+2]*3+1];
        triangle.v3.z = modelData.vertices[modelData.indices[i+2]*3+2];

        Vector3f normals = calculateNormal(triangle);
        normalizeVector(&normals);

        modelData.normals[modelData.surfaceNormals[i]*3] = normals.x;
        modelData.normals[modelData.surfaceNormals[i]*3+1] = normals.y;
        modelData.normals[modelData.surfaceNormals[i]*3+2] = normals.z; 

        modelData.normals[modelData.surfaceNormals[i+1]*3] = normals.x;
        modelData.normals[modelData.surfaceNormals[i+1]*3+1] = normals.y;
        modelData.normals[modelData.surfaceNormals[i+1]*3+2] = normals.z; 

        modelData.normals[modelData.surfaceNormals[i+2]*3] = normals.x;
        modelData.normals[modelData.surfaceNormals[i+2]*3+1] = normals.y;
        modelData.normals[modelData.surfaceNormals[i+2]*3+2] = normals.z; 
    }

Обновление 4: если посмотреть дальше, кажется, что нормали файла .obj являются поверхностными нормалями, а мне нужны вершинные нормали.(Может быть)

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

Обновление 5: я переписал весь свой загрузчик и каким-то образом заставил его работать.Несмотря на то, что он затеняет должным образом, у меня все еще есть те линии сетки, которые вы можете видеть на моих исходных результатах.

Ответы [ 2 ]

1 голос
/ 28 апреля 2011

Ваша normalizeVector функция явно неверна.Деление на ноль никогда не является хорошей идеей.Должно работать, когда vecMag != 0.0 хотя.Как вы рассчитываете нормали?Используете кросс-продукт?Когда произойдет, если вы позволите OpenGL вычислить нормали?

0 голосов
/ 27 апреля 2011

Это может быть ошибка направления ваших нормалей - если они неправильные, то вы увидите только те полигоны, которые должны быть направлены от вас.

Попробуйте позвонить:

 glDisable(GL_CULL_FACE);

и посмотрите, изменится ли ваш вывод.

Учитывая, что мы видим ребра многоугольника, я бы также проверил:

 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...