Понимание glTexCoord2f(), glVertex3f() в OpenGL

Я пытаюсь встроить поддержку OculusRift в наше программное обеспечение для автомобильных симуляторов в нашем институте. Из-за того, как настроено программное обеспечение симулятора, мы решили исправить искажение из-за того, что клиентская сторона объектива создает список отображения с OpenGL для запуска первых тестов.

В основном, где я изо всех сил пытаюсь понять, как OpenGL делает рисунок (для списка отображения). Я использовал информацию из разных руководств, и если я правильно понимаю, следующий цикл for выберет координаты для Tex 0,1,2, сделает виньетирование и привяжет его к каждой ветке. glBegin(GL_TRIANGLES) будет автоматически рисовать треугольники из вершин.

Координаты вершин хранятся в структуре, на которую указывает адрес ov. Кроме того, у нас есть смещения для каждого цветового канала.

Верен ли следующий код, вырезанный с точки зрения OpenGL?

ovrHmd_CreateDistortionMesh(pHmd, eyeRenderDesc[eyeNum].Eye, eyeRenderDesc[eyeNum].Fov,
ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette, &meshData);

ovrDistortionVertex * ov = meshData.pVertexData;

// New compiled distortion-rendering display list
glNewList(drList, GL_COMPILE);

// Make triangles out of the vertices
glBegin(GL_TRIANGLES);

for (unsigned int vertNum = 0; vertNum < meshData.VertexCount; vertNum++) {
    // Tex0,1,2 have already been activated
    glMultiTexCoord2f(GL_TEXTURE0, ov->TanEyeAnglesR.x, ov->TanEyeAnglesR.y);
    glMultiTexCoord2f(GL_TEXTURE1, ov->TanEyeAnglesG.x, ov->TanEyeAnglesG.y);
    glMultiTexCoord2f(GL_TEXTURE2, ov->TanEyeAnglesB.x, ov->TanEyeAnglesB.y);
    glColor4f(
    (OVR::UByte)(ov->VignetteFactor * 255.99f),
    (OVR::UByte)(ov->VignetteFactor * 255.99f),
    (OVR::UByte)(ov->VignetteFactor * 255.99f),
    (OVR::UByte)(ov->TimeWarpFactor * 255.99f));
    glVertex3f(ov->ScreenPosNDC.x, ov->ScreenPosNDC.y, 0.5); // z: constant
    ov++;
}

glEnd();
glEndList();

person Skaveelicious    schedule 27.11.2014    source источник
comment
списки отображения и glBegin/glEnd устарели. Вместо этого создавайте VBO и используйте шейдеры.   -  person ratchet freak    schedule 27.11.2014
comment
Несмотря на то, что они устарели, они все равно должны работать (и я склонен использовать их из чистой лени :)). Ваш код выглядит нормально, можете ли вы сказать нам, что не работает?   -  person Martin Prazak    schedule 27.11.2014
comment
@ratchetfreak Само программное обеспечение в основном используется для разработки систем управления автомобилем и позволяет вам управлять автомобилем. Что происходит, так это то, что программное обеспечение написано на языке сценариев TCL с расширением c/c++, и я не могу просто переписать весь процесс рендеринга. Поддержка OVR будет экспериментальной (без искажения времени) и будет осуществляться вызовами DLL, работающей в качестве оболочки TCL для OculusSDK. Следовательно, использование списка отображения.   -  person Skaveelicious    schedule 27.11.2014
comment
@martin_pr, так как я новичок в OpenGL, я просто хотел знать, правильно ли я понял способ использования glTexCoord glColor и glVertex в порядке вызова. И из того, что вы прокомментировали, это выглядит нормально;)   -  person Skaveelicious    schedule 27.11.2014
comment
Да, glTexCoord и glColor нужно вызывать перед glVertex. Однако эти функции немного устарели, и комментарии к ответу ниже действительно имеют смысл :)   -  person Martin Prazak    schedule 27.11.2014
comment
@Skaveelicious: Да, все правильно, glVertex эффективно завершает вершины, принимая атрибуты last, указанные вами с помощью glColor, glTexCoord, glNormal и т. д., и связывая их с новой вершиной. На самом деле вам не нужно вызывать ничего, кроме glVertex для каждой вершины, потому что будут использоваться старые значения для всех этих состояний, если вы их не измените. Итак, скажем, у вас есть цвет для каждого треугольника, а не для каждой вершины, вы можете переместить glColor4f из этого цикла.   -  person Andon M. Coleman    schedule 27.11.2014
comment
Большое спасибо всем вам за вклад. Вы очень помогли мне получить более четкое представление. @AndonM.Coleman AndonM.Coleman Я не знал, что это так работает, большое спасибо.   -  person Skaveelicious    schedule 27.11.2014
comment
Есть ли особая причина, по которой вы выполняете рендеринг искажения самостоятельно, а не позволяете SDK делать искажение? SDK обычно использует максимально быстрый код для искажения, и этот код должен становиться лучше по мере появления новых SDK.   -  person Jherico    schedule 28.11.2014


Ответы (2)


Я пытаюсь встроить поддержку OculusRift в наше программное обеспечение для автомобильных симуляторов в нашем институте. Из-за того, как настроено программное обеспечение симулятора, мы решили исправить искажение из-за того, что клиентская сторона объектива создает список отображения с OpenGL для запуска первых тестов.

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

person datenwolf    schedule 27.11.2014
comment
Я разрабатываю это как свой тезис для экспериментального использования (см. мой комментарий выше для получения дополнительной информации). Парень, который разработал программное обеспечение и помогает мне, сказал мне, что я могу добиться некоторых первых экспериментальных результатов без искажения времени (используя константу), и для этого достаточно использовать одноразовый список отображения. - person Skaveelicious; 27.11.2014
comment
@Skaveelicious: даже если это так, вы перебираете вершины некоторой структуры данных сетки. Гораздо проще просто объединить данные меша в массив вершин OpenGL и выполнить один вызов glDrawArrays, чем вручную перебирать эту чертову штуку. - person datenwolf; 27.11.2014
comment
На самом деле проще просто позволить SDK выполнять рендеринг искажений или, если это невозможно по какой-либо причине, вытащить код OpenGL для искажения непосредственно из SDK Oculus (который является общедоступным) - person Jherico; 28.11.2014
comment
Джерико, приятно видеть вас здесь. Я делаю что-то вроде академического экспериментального решения (без искажения времени) для существующего программного обеспечения. Парень, который знает программное обеспечение вдоль и поперек, сказал мне, что лучше всего передать ему искажение Mesh в качестве списка отображения. Он будет вызывать мою функцию, которая была загружена как DLL в язык сценариев TCL, из своего цикла рендеринга и получать идентификатор списка отображения. Я попробовал то, что вы сказали, но интенсивное использование классов в SDK заставило меня потеряться. Кроме того, мне сказали, что они все еще используют OGL 2.x, поэтому я хотел, чтобы все было просто =/ - person Skaveelicious; 30.11.2014
comment
Вы не должны изучать реализацию SDK. Все, что вам нужно для искажения на основе SDK, доступно в заголовке OVR_CAPI.h (который представляет собой чистый C) с использованием configureRendering(), beginFrame() и endFrame(). - person Jherico; 01.12.2014

glColor4f(
  (OVR::UByte)(ov->VignetteFactor * 255.99f),
  (OVR::UByte)(ov->VignetteFactor * 255.99f),
  (OVR::UByte)(ov->VignetteFactor * 255.99f),
  (OVR::UByte)(ov->TimeWarpFactor * 255.99f));

glColor4f ожидает значения с плавающей запятой, зажатые между 0 и 1. Однако вы передаете ему байты. Возможно, вы путаете его с glColor4b?

person Jherico    schedule 28.11.2014
comment
Да, моя ошибка. Каждый день я узнаю что-то новое и следил за этим. Есть много других неправильных вещей, таких как координаты текстуры, их нужно преобразовать в первую очередь, и я должен перебирать индексы, а не вершины, в моем подходе. Я сейчас переписываю свой код, чтобы вместо этого использовать массивы элементов, что упростит извлечение данных из структуры meshData. - person Skaveelicious; 30.11.2014