2017-02-17 28 views
0

Я разрабатываю программу, описанную ниже. Я рисую два треугольника с разной глубиной. Для примера, я хотел бы разделить зеленый треугольник на видимую часть и скрытую часть. Затем, наконец, используя функцию смешивания, скрытая часть зеленого треугольника окрашена как прозрачная, а видимая часть окрашена как исходный цвет.OpenGL - ES рисование и смешивание

example

Теперь я пишу коды с использованием OpenGL-ES (с JNI). И у меня есть два вопроса.

Первое:

glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 

glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 
glUseProgram(gProgram); 
glGetUniformLocation(gProgram, "vColor"); 


const GLfloat gTriangleVertices1[] = 
{ 
    -0.5f, -0.5f, -0.5f, 
    0.0f, 0.5f, -0.5f, 
    0.5f, -0.5f, -0.5f, 
}; 
float color1[] = {1.0f, 0.0f, 0.0f}; 
const GLfloat gTriangleVertices2[] = 
{ 
    -0.7f, 0.0f, 0.3f, 
    0.5f, 0.3f, 0.3f, 
    0.5f, 0.0f, 0.3f, 
}; 
float color2[] = {0.0f, 1.0f, 0.0f}; 



int mColorHandle1; 
int mColorHandle2; 

glEnable(GL_BLEND); 
glEnable(GL_DEPTH_TEST); 
glClearDepthf(1.0f); 
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
glUniform4f(mColorHandle1, color1[0], color1[1], color1[2], color1[3]); 
glVertexAttribPointer(gvPositionHandle, 3, GL_FLOAT, GL_FALSE, 0, gTriangleVertices1); 
glEnableVertexAttribArray(gvPositionHandle); 
glDrawArrays(GL_TRIANGLES, 0, 3); 
glDepthFunc(GL_GREATER); 
//glDepthFunc(GL_LESS); 
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
glUniform4f(mColorHandle2, color2[0], color2[1], color2[2], color2[3]); 
glDrawArrays(GL_TRIANGLES, 3, 3); 
glDisableVertexAttribArray(gvPositionHandle); 

из этого кода, если я изменю glDepthFunc (GL_GREATER) в glDepthFunc (GL_LESS), результат показывает видимую и скрытую часть правильно. Однако я не понимаю, почему он показывает правильный ответ. Поскольку я добавил вершину gTriangleVertices1, но я не добавляю gTriangleVertices2. Даже я не добавляю вершин треугольника 2, это дает мне правильный ответ. Зачем?

Второй вопрос, я думаю, что правильно использовать функцию смешивания (я проверил, что он работает на глют/freeglut). но почему это не работает на gl-es.

///////////////////////// visible part ///////////////////////// 
glEnable(GL_BLEND); 
glEnable(GL_DEPTH_TEST); 
glClearDepthf(1.0f); 
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
glUniform4f(mColorHandle1, color1[0], color1[1], color1[2], color1[3]); 
glVertexAttribPointer(gvPositionHandle, 3, GL_FLOAT, GL_FALSE, 0, gTriangleVertices1); 
glEnableVertexAttribArray(gvPositionHandle); 
glDrawArrays(GL_TRIANGLES, 0, 3); 
glDepthFunc(GL_LESS); 
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
glUniform4f(mColorHandle2, color2[0], color2[1], color2[2], color2[3]); 
glDrawArrays(GL_TRIANGLES, 3, 3); 
glDisableVertexAttribArray(gvPositionHandle); 
glDisable(GL_DEPTH_TEST); 
glDepthFunc(GL_LESS); // same to initialize depth func 
///////////////////////// visible part ///////////////////////// 


///////////////////////// hidden part ///////////////////////// 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
glEnable(GL_DEPTH_TEST); 
glClearDepthf(1.0f); 
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
glUniform4f(mColorHandle1, color1[0], color1[1], color1[2], color1[3]); 
glVertexAttribPointer(gvPositionHandle, 3, GL_FLOAT, GL_FALSE, 0, gTriangleVertices1); 
glEnableVertexAttribArray(gvPositionHandle); 
glDrawArrays(GL_TRIANGLES, 0, 3); 
glDepthFunc(GL_GREATER); 
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
glUniform4f(mColorHandle2, color2[0], color2[1], color2[2], 0.5f); 
glDrawArrays(GL_TRIANGLES, 3, 3); 
glDisableVertexAttribArray(gvPositionHandle); 
///////////////////////// hidden part ///////////////////////// 

Я только добавил функцию смешивания. Если я использую только видимую/скрытую часть, она дает правильный результат. Однако, если я использую функцию смешивания, это дает странный результат, как показано ниже: он дает прозрачный скрытый зеленый треугольник. что случилось?

enter image description here

ответ

0

Первый вопрос:

Вы создали большую ошибку, говоря glDrawArrays(GL_TRIANGLES, 3, 3); как это производит переполнение на буфере. Результатом этого является неожиданным, но в вашем случае, если ваш компилятор, кажется, решили, что два массива вы определенные плотно упакованы:

const GLfloat gTriangleVertices1[] = 
{ 
    -0.5f, -0.5f, -0.5f, 
    0.0f, 0.5f, -0.5f, 
    0.5f, -0.5f, -0.5f, 
}; 
const GLfloat gTriangleVertices2[] = 
{ 
    -0.7f, 0.0f, 0.3f, 
    0.5f, 0.3f, 0.3f, 
    0.5f, 0.0f, 0.3f, 
}; 

И считаются

const GLfloat gTriangleVertices[] = 
{ 
    -0.5f, -0.5f, -0.5f, 
    0.0f, 0.5f, -0.5f, 
    0.5f, -0.5f, -0.5f, 
    -0.7f, 0.0f, 0.3f, 
    0.5f, 0.3f, 0.3f, 
    0.5f, 0.0f, 0.3f, 
}; 

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

Второй вопрос:

Смешение и буфер глубины не идут вместе. Вам нужно избегать этой комбинации. Я не буду объяснять причины здесь (найдите немного для этого), но результат не определен, и вы не можете его использовать. Используйте один или другой.

Если вы будете искать в Интернете, как решить эту проблему, вы не найдете правильного ответа на свою ситуацию, хотя она очень уникальна. То, что я предлагаю для общего решения для вашего случая, - добавить буфер трафарета.

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

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

+0

Почему использование смешанного и глубинного тестирования имеет разные результаты на разных графических процессорах? Если вы нарисуете что-то полупрозрачное и еще один полупрозрачный объект перед ним, тогда нет проблем, если вы нарисуете его за ним, затем введите глубину. –

+0

@ Bálint Я тоже так думал, но потом я увидел некоторые результаты, которые кажутся полностью уничтожить буфер глубины. Проверьте результаты в этом вопросе: https://stackoverflow.com/questions/35893742/using-texture-image-with-alpha-makes-mesh-see-through/35912027#35912027 –

 Смежные вопросы

  • Нет связанных вопросов^_^