Конничива! Сегодня, как я и обещал, у нас речь пойдет о текстурировании. Точнее о мультитекстурировании. Представьте что у вас есть карта уровня, на которую было бы неплохо добавить тени. Со стенсильными тенями у вас пока не сложилось, поэтому вы решаете схитрить и нарисовать их прямо поверх текстуры. Хорошенько обдумав этот вариант, вы решаете его оптимизировать – тени нарисовать на отдельной текстуре. Это неплохое решение, которое было весьма распространено (да и сейчас оно не теряет своей актуальности). Вот только для его реализации нам потребутся механизм накладывающий за один проход несколько текстур на полигон. Итак, встречайте – мультитекстурирование.

    Суть заключается в том что перед тем как треугольник будет растеризован и “закатан” в буфер кадра, его прошоняют по так называемым текстурным блокам. С каждым блоком связана текстура, парамтры её применения к треугольнику и способ фильтрации. Сначала к отрисовываемому объекту применяется первый текстурный блок (с индексом “0”), затем второй (с индексом “1”) и так далее. Самоей замечательное в том что нам не придется менять или дорабатывать код иницилизации текстур, всё что нам надо сделать так это инициализировать текстурные блоки. Делается это следующим образом:

    // указываем системе что все настройки, которые будут установлены далее,
    // точнее до следующего вызова glActiveTextureARB, будут относиться к первому 
    // текстурному блоку
    glActiveTextureARB( GL_TEXTURE0_ARB );
    // в первом текстурном блоке будет установлена 2D текстура
    glEnable( GL_TEXTURE_2D );
    // сосбственно хэндл текстуры
    glBindTexture( GL_TEXTURE_2D , TextureHandle );
    // параметр отображения, в данном примере мы сообщаем что нам не интересно какой
    // цвет был у текселя до применения этого текстурного блока, теперь у него будет 
    // цвет соответствующего текселя текстуры
    // если бы вы указали  GL_MODULATE, то получили бы 
    // текст полигона умноженного на цвет текселя текстуры
    glTexEnvi( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_REPLACE );
	
    // ну тут всё аналогично – теперь работаем с первым текстуным блоком
    glActiveTextureARB( GL_TEXTURE1_ARB );
    // опять 2D текстура
    glEnable( GL_TEXTURE_2D );
    // накладываем вторую текстуру
    glBindTexture( GL_TEXTURE_2D , FilterHandle );
    // а вот теперь мы говорим что после применения второго текстурного блока
    // цвет текселя полигона рассчитывается как произведение текстуры второго блока
    // на цвет текселя полученного на предыдущем шаге
    glTexEnvi( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_MODULATE );

    Изменения немного коснулись функций назначения текстурных координат. Теперь это делается с помощью функций glMultiTexCoord2fARB, где первый параметр это GL_TEXTURE0_ARB, GL_TEXTURE1_ARB и так далее. Код отрисовки квадрата будет следующим:

    glActiveTextureARB( GL_TEXTURE0_ARB );
    glBindTexture( GL_TEXTURE_2D , TextureHandle );

    glActiveTextureARB( GL_TEXTURE1_ARB );
    glBindTexture( GL_TEXTURE_2D , FilterHandle );

    glBegin( GL_QUADS );
	    glMultiTexCoord2fARB( GL_TEXTURE0_ARB , 0.0 , 1.0 );
	    glMultiTexCoord2fARB( GL_TEXTURE1_ARB , 0.0 , 1.0 );
	    glColor3f( 1 , 0 , 0 );glVertex3f( -1.0f , -1.0f , 0.0f );

	    glMultiTexCoord2fARB( GL_TEXTURE0_ARB , 0.0 , 0.0 );
	    glMultiTexCoord2fARB( GL_TEXTURE1_ARB , 0.0 , 0.0 );
	    glColor3f( 0 , 1 , 0 );glVertex3f( -1.0f ,  1.0f , 0.0f );

	    glMultiTexCoord2fARB( GL_TEXTURE0_ARB , 1.0 , 0.0 );
	    glMultiTexCoord2fARB( GL_TEXTURE1_ARB , 1.0 , 0.0 );
	    glColor3f( 0 , 0 , 1 );glVertex3f(  1.0f ,  1.0f , 0.0f );

	    glMultiTexCoord2fARB( GL_TEXTURE0_ARB , 1.0 , 1.0 );
	    glMultiTexCoord2fARB( GL_TEXTURE1_ARB , 1.0 , 1.0 );
	    glColor3f( 1 , 1 , 0 );glVertex3f(  1.0f , -1.0f , 0.0f );
    glEnd();

    glActiveTextureARB( GL_TEXTURE0_ARB );
    glBindTexture( GL_TEXTURE_2D , 0 );

    glActiveTextureARB( GL_TEXTURE1_ARB );
    glBindTexture( GL_TEXTURE_2D , 0 );

    Вот собственно и всё на сегодня. Если возникнут вопросы, то вы знаете када об этом можно написать.

    ЗЫ Исходники.