android - Как нарисовать каркас над объектом в opengl 2.0?

У меня есть объект тетраэдра, созданный в openGL ES 2.0. Чего я пытаюсь добиться, так это показать фактический каркас многоугольника поверх его основного цвета. Есть ли метод для достижения этого эффекта?

Кроме того, мой тетраэдр розовый. Как я могу изменить его цвет?


person Community    schedule 30.01.2012    source источник


Ответы (3)


В дополнение к тому, что сказал Джав. Вместо увеличения всего объекта (оптимальная величина которого всегда зависит от объекта и текущего вида) для предотвращения артефактов z-борьбы, вы также можете использовать смещение полигона (используя glPolygonOffset), основным применением которого действительно являются каркасные наложения.

В основном он работает, немного регулируя значения глубины результирующих фрагментов, чего вы не можете добиться по-другому в ES, так как вы не можете писать в буфер глубины (что, я думаю, является причиной того, что они не удалили его из ES, как они это сделали в настольный GL 3+). Таким образом, вы в основном визуализируете свой твердотельный объект и свою линейную версию объекта, используя одни и те же вершины, но используя конфигурацию смещения полигона для твердотельного объекта, которая немного увеличивает значения глубины результирующих фрагментов (отталкивает их от зрителя), таким образом размещая треугольники всегда позади линий в пространстве обзора (или на самом деле в пространстве окна). Дополнительную информацию см. здесь.

Хотя в случае с тетраэдром могут возникнуть некоторые проблемы из-за его очень острых краев.

person Christian Rau    schedule 30.01.2012

1: Сначала нарисуйте свой объект как обычно, а затем нарисуйте его снова (с другим шейдером, иначе он будет того же цвета, что и объект и, следовательно, невидим), используя GLES20.GL_LINES, GL_LINE_LOOP или GL_LINE_STRIP.
Возможно, вы захотите слегка масштабируйте объект при рисовании линий, чтобы проверка глубины не решила, что линии находятся за объектом, и не проигнорировала их.

2: Это делается в вашем шейдере, установите для gl_FragColor значение vec4, содержащее желаемые значения rgba для сплошного цвета.

person Jave    schedule 30.01.2012
comment
Спасибо за ответ, но я не могу правильно понять синтаксис. Я работаю с примером здесь: blog.shayanjaved.com/2011/03/ 13/shaders-android И gl_FragColor не определен. - person ; 03.02.2012
comment
Если вы хотите узнать больше о шейдерах и GLSL, я рекомендую вам обратиться к RenderMonkey, где есть множество примеров и хорошая среда для программирования шейдеров: developer.amd.com/archive/gpu/rendermonkey/pages/default.aspx - person Jave; 03.02.2012

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

float coloredcube[] = { 2, 2, 2, 1, 0, 0, -2, 2, 2, 0, 1, 0, -2, -2, 2, 0,
        0, 1, 2, -2, 2, 1, 1, 0, 2, 2, -2, 1, 0, 1, -2, 2, -2, 0, 1, 1, -2,
        -2, -2, 1, 1, 1, 2, -2, -2, 0, 0, 0

};
short indices[] = { 0, 1, 2, 0, 2, 3, //back

        0, 4, 7, //right
        0, 7, 3,

        7, 6, 2, //bottom
        7, 2, 3,

        4, 5, 6, //front
        4, 6, 7,

        5, 1, 2, //left
        5, 2, 6,

        0, 1, 5, 0, 5, 4 //top
        };

short lineindices[] = { 0, 1, 1, 2, 0, 2, 2, 3,

0, 4, 4, 7, 0, 7, 7, 3,

7, 6, 6, 2, 7, 2, 4, 5,

5, 6, 4, 6, 5, 2, 1, 5, 0, 5, 0, 3 };

glVertexAttribPointer(iPosition, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float),coloredcube);
glEnableVertexAttribArray(iPosition);
glVertexAttribPointer(iColor, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float),coloredcube + 3);
glEnableVertexAttribArray(iColor);

// offset the filled object to avoid the stitching that can arise when the wireframe lines are drawn
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(2.0f, 2.0f);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, indices);
glDisable(GL_POLYGON_OFFSET_FILL);

//Then disable the vertex colors and draw the wire frame with one constant color
glDisableVertexAttribArray(iColor);
glLineWidth(1.0f);
GLfloat color[4] = { 1.0f, 0.0f, 0.0f, 0.5f };
glVertexAttrib4fv(iColor, color);
glDrawElements(GL_LINES, 36, GL_UNSIGNED_SHORT, lineindices);

Похожий пример можно найти в «Руководстве по программированию OpenGL ES 2.0», стр. 109,110.

person BlackAdder    schedule 01.08.2013