2009-08-21 3 views
2

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

Вот мой код:

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

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); 

Тогда я установка О

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 Я получитьthis, но я хочу this (или без текстуры this).

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

+0

Что вы пытаетесь достичь? прозрачный объект с твердыми пикселями? или твердый объект с некоторыми прозрачными текстурами, показывающими сплошной цвет внизу? –

+0

более поздний: твердый объект с некоторыми прозрачными текстурами, показывающими сплошной цвет внизу? – Alexandru

+0

спасибо за обновление ... И ОПРЕДЕЛЕННО сортируйте свою Z-буферизацию, как я предложил. – Goz

ответ

3

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

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

+0

Я не согласен, что все должно быть сделано с использованием шейдеров. Но вы избили меня на 19 секунд ;-) – hirschhornsalz

+0

OpenGL 3.X полностью отменил части FFP, шейдеры - это будущее. –

+0

Я не хочу текстур. Мне нужен один материал и одна текстура (например, живопись (текстура) на сером металле (материал)). Я согласен с тем, что рисование геометрии дважды - пустая трата времени, и, возможно, проблема, поэтому я ищу альтернативу. – Alexandru

-1

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

+0

Pixelshaders проще, чем мультитекстурирование? – hirschhornsalz

+0

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

1

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

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

0

Это просто дикая догадка, поскольку вы не смогли предоставить никаких скриншотов о том, что представляет собой настоящая проблема, но почему вы отключите проверку глубины? Наверное, вы хотите включить тестирование глубины на первом проходе со стандартным 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

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

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

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