Сейчас я делаю скрул шутер-леталка сверху, на подобии Tyrian, Raptor, Raiden и т.п. Пишу на с++ с использованием SDL+OpenGL
Я использовал для вывода спрайта затекстурированный полигон, каждый спрайт(его текстура) находиться в отдельных *.png файлах.
Эта процедура имеет примерно такой вид (процедура 1):
//рисуем затекстурированый полигон
void DrawTXT (float x,
float y,
float dX,
float dY,
float delta,
int center)
{
glLoadIdentity();
glTranslatef(x,y,0);
glRotatef(delta,0,0,-1);
if (center==1) {glTranslatef(-dX/2,-dY/2,0);}//смещаем по центре
glBegin( GL_QUADS );
// Верхний левый угол
glTexCoord2i(0,0); glVertex2f( 0, 0 );
//Нижний левый угол
glTexCoord2i( 0, 1 ); glVertex2f( 0, dY );
//Нижний правый угол
glTexCoord2i( 1, 1 ); glVertex2f( dX, dY );
//Верхний правый угол
glTexCoord2i( 1, 0 ); glVertex2f( dX, 0 );
glEnd();
glLoadIdentity();
}
Захотелось использовать одну общую текстуру (с набором спрайтов). Спрайт получать закрашивая полигон задавая текстурные координаты, и процедура стала иметь вид (процедура 2):
//рисуем затекстурированый полигон из общей текстуры
void _DrawTXT (float W,//размеры всей текстуры
float H,
float t_x,//координаты верхнего левого угла в текстуре
float t_y,
float t_dx,//размеры куска текстуры
float t_dy,
float x,
float y,
float dX,
float dY,
float delta,//угол поворота
int center)
{
glLoadIdentity();
glTranslatef(x,y,0);
glRotatef(delta,0,0,-1);
if (center==1) {glTranslatef(-dX/2,-dY/2,0);}//смещаем по центре
glBegin( GL_QUADS );
// Верхний левый угол
glTexCoord2f((t_x/W),(t_y/H)); glVertex2f( 0, 0 );
//Нижний левый угол
glTexCoord2f((t_x/W),((t_y+t_dy)/H)); glVertex2f( 0, dY );
//Нижний правый угол
glTexCoord2f(((t_x+t_dx)/W),((t_y+t_dy)/H)); glVertex2f( dX, dY );
//Верхний правый угол
glTexCoord2f(((t_x+t_dx)/W), (t_y/H) ); glVertex2f( dX, 0 );
glEnd();
glLoadIdentity();
}
В игре для летающих объектов хочется сделать тень, отбрасываемую ими на землю. Посоветовали использовать для этих целей буфер трафарета, вот примерно так это выглядит:
//цвета теней не смешиваються!!! работает с глюками при выводе уровня из единой текстуры
glEnable(GL_STENCIL_TEST);//включаем трафарет
glStencilFunc(GL_ALWAYS, 1, 255);//в том месте где рисуется трафарет значение буфера заменяем на 1
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glEnable(GL_ALPHA_TEST); //надо отсечь рисования прозрачных пикселей уровня
glAlphaFunc(GL_GREATER,0.5f); //выводим только те пиксели уровня у которых alpha > 0.5f
level_draw();//уровень является трафаретом-только на нем видна тень
glStencilFunc(GL_EQUAL, 1, 255);// тень будет рисоваться только в тех местах,где значение в буфере 1
glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
glAlphaFunc(GL_GREATER,0.45f); //выводим только те пиксели тени у которых alpha > 0.45f
player_shadow_draw();
glDisable(GL_ALPHA_TEST);
glDisable(GL_STENCIL_TEST);//отключаем трафарет
Если использовать для вывода трафарета level_draw процедуру 1, то тень рисуется как надо-только на трафарете, учитываются спрайты с "дырками" альфа канала (на дырках тени не должно быть), тени не смешиваются. НО мне хочется использовать для вывода level_draw процедуру 2, так проще. Если так сделать то начинаются появлятся глюки-тени иногда мигают, пропадают на некоторое время или просто не рисуются. Я думаю что это из-за альфа теста и альфа функа , если их убрать тени будут рисоваться на всех спрайтах level_draw, включая "дыры" альфа канала.
Хочется вывода нормальных теней при использовании процедуры 2, как при использовании процедуры 1. То есть, чтобы тени не смешивались, хотя бы не рисовались на "дырах". Как это исправить ?
ЗЫ:я не очень хорошо знаю OpenGL(