Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для компьютеров > C++

Ответ
 
Опции темы
Старый 08.09.2009, 16:49   #1
aureli0
ПроЭктировщик
 
Регистрация: 19.03.2007
Сообщений: 134
Написано 10 полезных сообщений
(для 20 пользователей)
2d в OpenGL. вывод тени от спрайта

Сейчас делаю игрушку-скролл шутер. Появились трудности с выводом теней.
На данный момент тени от спрайтов вывожу следующим образом:
void enemy_air_shadow_draw()//рисование тени от воздушных юнитов
 {
  glColor4f(0,0,0,0.5);
  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  for(i=0; i < enemy_max; i++) 
   {
    if (enemy[i].air==1)
     {
      glBindTexture(GL_TEXTURE_2D,enemy_texture[enemy[i].texture]);
      DrawTXT (enemy[i].x*grid_DX+enemy_move_x[i]+x_cam+0.2*(enemy[i].x*grid_DX+enemy_move_x[i]-win_DX/2),
               enemy[i].y*grid_DY+enemy_move_y[i]+y_cam+40,
               enemy[i].dx,
               enemy[i].dy,
               0,1);  
     } 
   }
  glColor4f(1,1,1,1);
  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
 }
Но здесь есть ряд проблем: тени выводятся на все элементы уровня и задний фон, а также они смешиваються, становясь темнее.
Как сделать так, чтобы тень появлялась ТОЛЬКО на декорациях уровня(зеленые элементы), а не на картинке заднего плана(космос)?
Как исправить смешение теней?
Миниатюры
Нажмите на изображение для увеличения
Название: screen1.jpg
Просмотров: 1312
Размер:	117.8 Кб
ID:	7517  

Последний раз редактировалось aureli0, 08.09.2009 в 20:54.
(Offline)
 
Ответить с цитированием
Старый 08.09.2009, 17:00   #2
jimon
 
Сообщений: n/a
Ответ: 2d в OpenGL. вывод тени от спрайта

aureli0
можно использовать буфер трафарета (stencil), принцип простой : рисуем задний фон и в трафарет для пикселя пишется 0, рисуем декорации - в трафарет для пикселя пишется 1, ставим условие что рисуем пиксель только если в трафарете 1 и рисуем тени, таким же способом делается отсечения смешивания - после рисования тени пишем в буфер трафарета 2, в итоге следуйшие пиксели тени не смогут быть выведены на этот место потому что в буфере трафарета стоит не 1, а 2

ps. никогда не юзал stencil (но буду), вышенаписанное это мои теоретические знания
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
aureli0 (08.09.2009)
Старый 08.09.2009, 20:34   #3
aureli0
ПроЭктировщик
 
Регистрация: 19.03.2007
Сообщений: 134
Написано 10 полезных сообщений
(для 20 пользователей)
Re: 2d в OpenGL. вывод тени от спрайта

спасибо)
эээээ, значит както так??

//ИНИЦИАЛИЗАЦИЯ
// очищаем все буферы
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// разрешаем тест трафарета
glEnable(GL_STENCIL_TEST);

//Где то в главном цикле программы

рисуем задний фон

//в трафарет для пикселя пишется 0
glStencilFunc(GL_ALWAYS, 0, 0);

рисуем дикорации

//в трафарет для пикселя пишется 1
glStencilFunc(GL_ALWAYS, 1, 0);
//ставим условие что рисуем пиксель только если в трафарете 1
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

рисуем тень

//в трафарет для пикселя пишется 2-делаем отсечение смешивания
glStencilFunc(GL_ALWAYS, 2, 0);

рисуем все остальное


смотрел сюда
http://www.opengl.org.ru/books/open_gl/chapter4.12.html

с синтаксисом glStencilFunc и glStencilFunc я так и не разобрался(

У себя ы программе сделал так:

//гдето в главном цикле
//в трафарет для пикселя пишется 0
glStencilFunc(GL_ALWAYS, 0, 0);

level_draw();
enemy_ground_draw();//рисование и анимация наземных врагов
starwind_draw();

//в трафарет для пикселя пишется 1
glStencilFunc(GL_ALWAYS, 1, 0);
//ставим условие что рисуем пиксель только если в трафарете 1
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

player_shadow_draw();
enemy_air_shadow_draw();

//в трафарет для пикселя пишется 2-делаем отсечение смешивания
glStencilFunc(GL_ALWAYS, 2, 0);


enemy_air_draw();//рисование и анимация летающих врагов
enemy_blast_draw();//рисуем патрон врага

player_draw();//Рисуем корабль игрока
player_ammo_draw();//Рисуем патрон игрока

effect_draw();

ничего не получилось. картинка осталась без изменения
что делать?

Последний раз редактировалось aureli0, 08.09.2009 в 20:58.
(Offline)
 
Ответить с цитированием
Старый 08.09.2009, 22:22   #4
aureli0
ПроЭктировщик
 
Регистрация: 19.03.2007
Сообщений: 134
Написано 10 полезных сообщений
(для 20 пользователей)
Re: 2d в OpenGL. вывод тени от спрайта

получилось вот таким образом, но тени смешиваются,как это исправить?
    // Значение, которым будет заполняться буфер стенсила при его очистке
    glClearStencil(0);//значение фона буфера стенсила фона
    glStencilMask(0xFF);//Определяем, какие биты могут писаться в стенсил буфер
    glClear( GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);// Очищаем все буферы

    //Задний фон
    glColor4f(1,1,1,1);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D,background_texture);
    DrawTXT(win_DX/2,win_DY/2,win_DX,win_DY,0,1);

      level_draw();
      enemy_ground_draw();//рисование и анимация наземных врагов
      starwind_draw();

      glEnable(GL_STENCIL_TEST);//включаем трафарет
      //определяем область где тень рисуется
      glStencilFunc(GL_NEVER, 1, 0);
      //в том месте где рисуется трафарет значение буфера заменяем на 1
      glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
      level_draw();//уровень является трафаретом-только на нем видна тень
      // тень будет рисоваться только в тех местах,где значение в буфере 1
      glStencilFunc(GL_EQUAL, 1, 255);
      player_shadow_draw();
      enemy_air_shadow_draw();
      glDisable(GL_STENCIL_TEST);//отключаем трафарет

      enemy_air_draw();//рисование и анимация летающих врагов
      enemy_blast_draw();//рисуем патрон врага

      player_draw();//Рисуем корабль игрока
      player_ammo_draw();//Рисуем патрон игрока

      effect_draw();
(Offline)
 
Ответить с цитированием
Старый 08.09.2009, 22:39   #5
jimon
 
Сообщений: n/a
Ответ: 2d в OpenGL. вывод тени от спрайта

ммм по-идее так должно работать
      glEnable(GL_STENCIL_TEST);//включаем трафарет
      //мы в любом случае будем писать в трафарет
      glStencilFunc(GL_ALWAYS, 0, 255);
      //в том месте где рисуется трафарет значение буфера заменяем на 1
      glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
      level_draw();//уровень является трафаретом-только на нем видна тень
      // тень будет рисоваться только в тех местах,где значение в буфере 1
      glStencilFunc(GL_EQUAL, 1, 255);
      glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
      player_shadow_draw();
      enemy_air_shadow_draw();
      glDisable(GL_STENCIL_TEST);//отключаем трафарет
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
aureli0 (08.09.2009)
Старый 08.09.2009, 22:50   #6
aureli0
ПроЭктировщик
 
Регистрация: 19.03.2007
Сообщений: 134
Написано 10 полезных сообщений
(для 20 пользователей)
Re: 2d в OpenGL. вывод тени от спрайта

  // Значение, которым будет заполняться буфер стенсила при его очистке
  glClearStencil(0);//значение фона буфера стенсила фона
  glStencilMask(0xFF);//Определяем, какие биты могут писаться в стенсил буфер
  //Очищаем экран перед рисованием и буфер стенсила
  glClear( GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);// Очищаем все буферы

рисуем задник

      glEnable(GL_STENCIL_TEST);//включаем трафарет
      //мы в любом случае будем писать в трафарет
      glStencilFunc(GL_ALWAYS, 1, 255);  //!!!!!!!!!!! не 0 а 1
      //в том месте где рисуется трафарет значение буфера заменяем на 1
      glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
      level_draw();//уровень является трафаретом-только на нем видна тень
      // тень будет рисоваться только в тех местах,где значение в буфере 1
      glStencilFunc(GL_EQUAL, 1, 255);
      glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
      player_shadow_draw();
      enemy_air_shadow_draw();
      glDisable(GL_STENCIL_TEST);//отключаем трафарет
заработало так, причем цвета теней больше не смешиваются ура
спасибо)

А как сделать чтобы тени еще не выводились на дырах(альфа канал) в спрайтах?
(Offline)
 
Ответить с цитированием
Старый 08.09.2009, 23:05   #7
jimon
 
Сообщений: n/a
Ответ: 2d в OpenGL. вывод тени от спрайта

А как сделать чтобы тени еще не выводились на дырах(альфа канал) в спрайтах?
хм, ну можно сделать такой альфа тест что при alpha < 0.5 пиксель не будет выводится, собсно в буфере трафарета будет 0 и не будет там тень рисоваться
 
Ответить с цитированием
Старый 08.09.2009, 23:08   #8
aureli0
ПроЭктировщик
 
Регистрация: 19.03.2007
Сообщений: 134
Написано 10 полезных сообщений
(для 20 пользователей)
Re: 2d в OpenGL. вывод тени от спрайта

тоже теперь не все хорошо тени от объектов одного типа режут друг друга
Миниатюры
Нажмите на изображение для увеличения
Название: scr1.jpg
Просмотров: 1145
Размер:	128.3 Кб
ID:	7518  
(Offline)
 
Ответить с цитированием
Старый 08.09.2009, 23:15   #9
jimon
 
Сообщений: n/a
Ответ: 2d в OpenGL. вывод тени от спрайта

aureli0
так приделай еще альфа тест для теней тоже с каким нибудь условием что если альфа = 0 то не рисовать пиксель
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
aureli0 (08.09.2009)
Старый 08.09.2009, 23:35   #10
aureli0
ПроЭктировщик
 
Регистрация: 19.03.2007
Сообщений: 134
Написано 10 полезных сообщений
(для 20 пользователей)
Re: Ответ: 2d в OpenGL. вывод тени от спрайта

Сообщение от jimon Посмотреть сообщение
aureli0
так приделай еще альфа тест для теней тоже с каким нибудь условием что если альфа = 0 то не рисовать пиксель
эт я понял только опять же какие параметры давать в glAlphaFunc?

//цвета теней не смешиваються!!!
      glEnable(GL_STENCIL_TEST);//включаем трафарет
      //мы в любом случае будем писать в трафарет
      glStencilFunc(GL_ALWAYS, 1, 255);
      //в том месте где рисуется трафарет значение буфера заменяем на 1
      glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

      level_draw();//уровень является трафаретом-только на нем видна тень

      // тень будет рисоваться только в тех местах,где значение в буфере 1
      glStencilFunc(GL_EQUAL, 1, 255);
      glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_EQUAL,1);//выводить тени только на видимых пикселях с альфа 1
      player_shadow_draw();
      enemy_air_shadow_draw();
glDisable(GL_ALPHA_TEST);
      glDisable(GL_STENCIL_TEST);//отключаем трафарет
по идее тени должны рисоваться только на пикселях с альфа=1, но тени просто полностью пропали(( опять я чето перепутал)

Последний раз редактировалось aureli0, 08.09.2009 в 23:41.
(Offline)
 
Ответить с цитированием
Старый 08.09.2009, 23:39   #11
jimon
 
Сообщений: n/a
Ответ: 2d в OpenGL. вывод тени от спрайта

хм
//цвета теней не смешиваються!!!
      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();//уровень является трафаретом-только на нем видна тень

      // тень будет рисоваться только в тех местах,где значение в буфере 1
      glStencilFunc(GL_EQUAL, 1, 255);
      glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);

glAlphaFunc(GL_GREATER,0.2f); //выводим только те пиксели тени у которых alpha > 0.2f

      player_shadow_draw();
      enemy_air_shadow_draw();
glDisable(GL_ALPHA_TEST);
      glDisable(GL_STENCIL_TEST);//отключаем трафарет
там где 0.2f надо будет эксперементировать, в принципе если тени наложатся то в границе наложения будут небольшие баги, имхо тени надо сумировать
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
aureli0 (09.09.2009)
Старый 09.09.2009, 00:02   #12
aureli0
ПроЭктировщик
 
Регистрация: 19.03.2007
Сообщений: 134
Написано 10 полезных сообщений
(для 20 пользователей)
Re: 2d в OpenGL. вывод тени от спрайта

вот спасибо)) теперь все как надо. Да глюки есть. Поменял значение с 0.2 на 0.4 границы пропали но тени стали четче ну и фиг с ним все здорово))
Еще раз спасибо))
(Offline)
 
Ответить с цитированием
Старый 14.09.2009, 22:25   #13
aureli0
ПроЭктировщик
 
Регистрация: 19.03.2007
Сообщений: 134
Написано 10 полезных сообщений
(для 20 пользователей)
Re: 2d в OpenGL. вывод тени от спрайта

опять появились проблемы с тенями. Раньше каждая текстура хранилась в отдельном файле, и все работало без проблем. Теперь я использую для вывода level один файл с несколькими текстурами-появились глюки:
то иень периодически пропадает, то пооявляется. В трафарет помимо level_draw я добавил еще наземных юнитов enemy_groumd_Draw. Так вот они стали тоже "моргать".

//цвета теней не смешиваються!!! работает с глюками при выводе уровня из 1 текстуры
      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();//уровень является трафаретом-только на нем видна тень
    //    enemy_ground_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();
        enemy_air_shadow_draw();
      glDisable(GL_ALPHA_TEST);
      glDisable(GL_STENCIL_TEST);//отключаем трафарет
чето гдето нето чтото с альфой?
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поворот спрайта nil0q Основной форум 4 15.09.2009 15:55
помогите! передвижение спрайта Jlemyp 2D-программирование 10 21.06.2009 21:09
Тени Yalenz 3D-программирование 9 10.03.2009 22:54
Как сделать анимацию спрайта? dimanche13 2D-программирование 29 17.04.2007 22:33


Часовой пояс GMT +4, время: 15:18.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com