Войти
ПрограммированиеФорумГрафика

[Решено] GLSL Multitexturing, (нубская) проблема

#0
12:43, 5 фев. 2011

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

Начал разбираться с GLSL Multitexturing.
Имеется следующие шейдеры.

//VERT

void main(void)
{
    gl_TexCoord[0]  = gl_MultiTexCoord0;
    //gl_TexCoord[1]  = gl_MultiTexCoord1;
    gl_Position = ftransform();
}
    ''', '''
//FRAG

uniform sampler2D Texture_0;
uniform sampler2D Texture_1;

void main (void)
{
    vec4 texel0, texel1, resultColor;

  texel0 = texture2D(Texture_0, gl_TexCoord[0].st);
  texel1 = texture2D(Texture_1, gl_TexCoord[0].st);

    //resultColor = mix(texel0, texel1, 0.1);
    resultColor = texel1;

    gl_FragColor = resultColor;
}
В программе рисую первую тектуру как бэкграунд без задействования шейдеров
Далее рисую teapot с задействованием шейдером.
В шейдер передаю две текстуры используя только 1 тектурный юнит GL_TEXTURE0

           glActiveTexture(GL_TEXTURE0)                                
           glBindTexture(GL_TEXTURE_2D, tex0)
           glUniform1i(glGetUniformLocation(program, 'Texture_0'), 0) 

           glActiveTexture(GL_TEXTURE0)
           glBindTexture(GL_TEXTURE_2D, tex1)
           glUniform1i(glGetUniformLocation(program, 'Texture_1'), 0)

Когда рендерю сцену, то изменение во фрагментном шейдере
    resultColor = texel1; на resultColor = texel0; не даёт эффекта.

На чайник всё время налаживается Texture_1(немогу добится наложения Texture_0 ).
Вопрос: такое ощущение что моя передача двух тектур используя 1 тектурный юнит заключается в том что я теряю информацию о первой тектуре(Texture_0) которая не рисуется на чайник при правке фрагментного шейдера resultColor = texel0;
Вполне возможно я не совсем правильно понимаю смысл Текстурных юнитов, может нельзя передавать две разные тектуры исползуя 1 текстурный юнит?
К сожалению исползование нескольких тектурных юнитов проверить не получается, программа валится с ошибкой при активировании второго, с этим я тоже не смог пока разобраться

           glActiveTexture(GL_TEXTURE0)                                
           glBindTexture(GL_TEXTURE_2D, tex0)
           glUniform1i(glGetUniformLocation(program, 'Texture_0'), 0) 

           glActiveTexture(GL_TEXTURE1)
           glBindTexture(GL_TEXTURE_2D, tex1)
           glUniform1i(glGetUniformLocation(program, 'Texture_1'), 1)

Если поможет вот полный код программы(python)
http://bpaste.net/show/13476/

Зараннее благодарен за помощ.


#1
12:51, 5 фев. 2011

diverlin

glActiveTexture(GL_TEXTURE0)
glEnable(GL_TEXTURE_2D)                               
glBindTexture(GL_TEXTURE_2D, tex0)

glActiveTexture(GL_TEXTURE1)
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, tex1)

glUniform1i(glGetUniformLocation(program, 'Texture_0'), 0) 
glUniform1i(glGetUniformLocation(program, 'Texture_1'), 1)
Нужно разрешать текстуры для каждой активной текстуры
#2
13:11, 5 фев. 2011

minuz
> Нужно разрешать текстуры для каждой активной текстуры
Заблуждение. Для шейдера все равно разрешены ли текстуры или нет. Читай http://www.opengl.org/wiki/GLSL_:_common_mistakes#Enable_Or_Not_To_Enable

#3
13:18, 5 фев. 2011

diverlin
> В программе рисую первую тектуру как бэкграунд без задействования шейдеров
Мешать FFP и шейдеры плохая практика, просто сделай простой шейдер для отрисовки с минимум возможностей и используй его, не мешай с FFP!

> может нельзя передавать две разные тектуры исползуя 1 текстурный юнит?
Можно, до тех пор пока в шейдерах используются правильные текстурные самплеры.

> программа валится с ошибкой при активировании второго
Проверь количество доступных текстурных юнитов, используй glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &value);

Когда начинаются проблемы желательно смотреть на вывод glGetError(); и проверять сообщения об ошибках при компиляции шейдеров.

#4
13:55, 5 фев. 2011

diverlin
> В шейдер передаю две текстуры используя только 1 тектурный юнит GL_TEXTURE0
я тоже так хочу но не получается - железо так не умеет

#5
14:23, 5 фев. 2011

diverlin
> Вполне возможно я не совсем правильно понимаю смысл Текстурных юнитов, может
> нельзя передавать две разные тектуры исползуя 1 текстурный юнит?

Ну разве что текстурными массивами.

#6
14:24, 5 фев. 2011

minuz
попробывал, не помогает.
у меня команда glActiveTexture(GL_TEXTURE1) вызывает сбой, незнаю почему.
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS) возвращает 32 (радеон 5550)

KpeHDeJIb
>Мешать FFP и шейдеры плохая практика, просто сделай простой шейдер для отрисовки с минимум возможностей и используй его, не мешай с FFP!
исключил рисование с помощью FFP, закоментив ненужное, не помогает.
как я писал уже выше
у меня команда glActiveTexture(GL_TEXTURE1) вызывает сбой, вот лог(если он конечно верный)

  File "/usr/lib/pymodules/python2.6/OpenGL/error.py", line 208, in glCheckError
    baseOperation = baseOperation,
GLError: GLError(
        err = 1282,
        description = 'invalid operation',
        baseOperation = glPopMatrix,
        cArguments = ()
даже при незадействованyx шейдерax, незнаю почему.
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS) возвращает 32 (радеон 5550).

#7
14:29, 5 фев. 2011

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

Executor
>Ну разве что текстурными массивами.
сейчас погуглим, попробуем, спасибо

#8
14:42, 5 фев. 2011

diverlin
> сейчас погуглим, попробуем, спасибо

В твоём случае они излишни.

#9
17:12, 5 фев. 2011

diverlin
> baseOperation = glPopMatrix,
Меня вот эта строчка настораживает, сейчас гляну весь код.

#10
17:21, 5 фев. 2011

>Меня вот эта строчка настораживает, сейчас гляну весь код.
полный вывод

Fragment shader(s) linked, vertex shader(s) linked. 

-1 2
32
Traceback (most recent call last):
  File "GLSL_uniform_multitexturing_TMP.py", line 18, in glLibTestErrors
    function()
  File "GLSL_uniform_multitexturing_TMP.py", line 236, in main
    glPopMatrix()
  File "/usr/lib/pymodules/python2.6/OpenGL/error.py", line 208, in glCheckError
    baseOperation = baseOperation,
GLError: GLError(
        err = 1282,
        description = 'invalid operation',
        baseOperation = glPopMatrix,
        cArguments = ()

line 236, glPopMatrix() согласованно с тем что http://bpaste.net/show/13476/

Я нашёл
http://www.pygame.org/project-glLib+Reloaded-1326-.html
там это работает(т.е. проблема не в моей HW), и glActiveTexture(GL_TEXTURE1) и glActiveTexture(GL_TEXTURE2) работают.
Только код там сложнее, пока что я не нашёл раздницы, разве что в инициализации должна быть раздница.

#11
17:34, 5 фев. 2011

diverlin

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

Самый первый glBindTexture делается без установки текущего активного текстурного юнита, надо сначала вызвать glActiveTexture.

У тебя когда рисуется screen-space квад лишний вызов glPushMatrix/glPopMatrix который ничего не делает, просто заметил, ничего страшного, но толку от него никакого.

В шейдере у тебя используется gl_MultiTexCoord, но нигде нету и намека на glMultiTexCoord.

Советую после каждой строчки в рендере, вставить вывод в лог значения возврата glGetError (если он не нулевой).

Опять же у тебя используется GLUT (я увидел glutInit), но нигде нету выставления значения глутовской функции рендера, там есть специальные функции для этого.

ЗЫ. После glGenTextures и перед glBindTexture ставь текстурный юнит тоже, чтобы порядок был, например 0-вой glActiveTexture(GL_TEXTURE0), потому что последующие операции вроде glTexParameteri выполняются на текущем активном юните, поэтому лучше все таки выбрать какой-то конкретный, но это не ошибка, я и сам раньше не ставил, это скорее хороший тон :)

#12
18:11, 5 фев. 2011

проблема решена исключением из программы GLUT

KpeHDeJIb
Спасибо за развёрнутый ответ и рекомендации, всё учту.
Кстати ваш пост помог мне решить проблему, проблема была в GLUT (у меня еще стоит какая-то свободная его реализация) либо в его неправильном использовании мной.
GLUT я использовал чтоб рисовать чайник, исключил все вызовы GLUT и никаких ошибок.

KpeHDeJIb
>я вижу ты пытаешься на один текстурный юнит повешать две текстуры - такое сделать нельзя, вторая затрет первую.
теперь буду знать, в принципе всё логично.

Всем спасибо! Сейчас буду пробовать мультитекстуринг с использованием разных текстурных юнитов.

#13
18:13, 5 фев. 2011

diverlin
> Сейчас буду пробовать мультитекстуринг
ты не путай термины - а то отцы не поймут, multitexture - это не шейдера :)

#14
18:44, 5 фев. 2011

innuendo
ну я имел ввиду Multitexture with GLSL,.
http://www.opengl.org/wiki/Multitexture_with_GLSL
я думал всё что GLSL это может так же называться шейдером. multitexture можно делать и классичеким FFP и GLSL.
Но я могу и ошибаться, много читал(путался) а сделал реально мало.

ПрограммированиеФорумГрафика

Тема в архиве.

Тема закрыта.