визуализировать прозрачные текстуры - PullRequest
2 голосов
/ 21 августа 2009

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

Вот мой код:

Сначала я установил материал:

   glDisable(GL_COLOR_MATERIAL);
   glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
   glColor4f(0.00, 0.00, 0.00, 1.00);
   glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
   glColor4f(0.80, 0.80, 0.80, 1.00);
   glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
   glColor4f(0.01, 0.01, 0.01, 1.00);
   glEnable(GL_COLOR_MATERIAL);

Затем я настраиваю VBO

   glBindTexture(GL_TEXTURE_2D, object->texture);
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

   glBindBuffer(GL_ARRAY_BUFFER, object->object);
   glVertexPointer(3, GL_FLOAT, sizeof(Vertex), ver_offset);
   glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), tex_offset);
   glNormalPointer(GL_FLOAT, sizeof(Vertex), nor_offset);

И наконец я рисую объект

   glEnable(GL_BLEND);
   glDisable(GL_DEPTH_TEST);

   glDisable(GL_TEXTURE_2D);
   glBlendFunc(GL_ONE, GL_ZERO);
   glDrawArrays(GL_TRIANGLES, 0, object->num_faces);

   glEnable(GL_TEXTURE_2D);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   glDrawArrays(GL_TRIANGLES, 0, object->num_faces);

   glDisableClientState(GL_VERTEX_ARRAY);
   glDisableClientState(GL_TEXTURE_COORD_ARRAY);

   glDisable(GL_BLEND); 
   glEnable(GL_DEPTH_TEST);

Я пытался передать разные аргументы в glBlendFunc () без преобладания. Я загрузил источник здесь: http://dpaste.com/83559/

UPDATE Я получаю это , но я хочу это (или без текстуры это ).

2-е и 3-е изображение производятся с glm . Я изучил источники, но так как мои знания OpenGL ограничены, я мало что понял.

Ответы [ 5 ]

3 голосов
/ 21 августа 2009

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

Мультитекстурирование будет просто производить выборку из двух текстурных блоков, а геометрию рисовать только один раз. Вы можете сделать это с помощью шейдеров (так, как на самом деле все должно быть сделано), или вы все равно можете использовать конвейер с фиксированной функцией (см .: http://bluevoid.com/opengl/sig00/advanced00/notes/node62.html)

1 голос
/ 21 августа 2009

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

То, чего вы хотите достичь, можно сделать, используя мультитекстурирование .

0 голосов
/ 23 августа 2009

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

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

0 голосов
/ 21 августа 2009

Это всего лишь дикая догадка, поскольку вы не смогли предоставить скриншоты того, что представляет собой настоящая проблема, но почему вы отключаете тест глубины? Конечно, вы хотите включить проверку глубины на первом проходе со стандартным GL_LESS, а затем сделать второй проход с GL_EQUAL?

Edit:

е

glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);  // ie do not disable
glDepthFunc( GL_LESS );   // only pass polys have a z value less than ones already in the z-buffer (ie are in front of any previous pixels)

glDisable(GL_TEXTURE_2D);
glBlendFunc(GL_ONE, GL_ZERO);
glDrawArrays(GL_TRIANGLES, 0, object->num_faces);

// for the second pass we only want to blend pixels where they occupy the same position 
// as in the previous pass.  Therefore set to equal and only pixels that match the
// previous pass will be blended together.
glDepthFunc( GL_EQUAL );

glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDrawArrays(GL_TRIANGLES, 0, object->num_faces);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

glDisable(GL_BLEND); 
0 голосов
/ 21 августа 2009

Это будет намного проще с пиксельными шейдерами. в противном случае я думаю, что вам нужен многопроходный рендеринг или более одной текстуры Вы можете найти подробную информацию здесь: http://www.opengl.org/resources/faq/technical/transparency.htm

...