Вверх ↑
Этот топик читают: Гость
Гость
Ответов: 17029
Рейтинг: 0
#1: 2009-04-28 18:13:49 правка | ЛС | профиль | цитата


Редактировалось 3 раз(а), последний 2021-05-22 09:25:45
карма: 0

0
Администрация
Ответов: 15295
Рейтинг: 1519
#2: 2009-04-28 18:22:20 ЛС | профиль | цитата
ExampleOpenGl*.sha
карма: 27
0
Гость
Ответов: 17029
Рейтинг: 0
#3: 2009-04-28 18:23:54 правка | ЛС | профиль | цитата


Редактировалось 3 раз(а), последний 2021-05-22 09:25:45
карма: 0

0
Ответов: 66
Рейтинг: 8
#4: 2009-04-28 18:34:11 ЛС | профиль | цитата
Dilma, не плохо былобы создать раздел посвещеный OpenGL.
карма: 0

0
Администрация
Ответов: 15295
Рейтинг: 1519
#5: 2009-04-28 18:50:54 ЛС | профиль | цитата
для чего? схемы с использованием opengl выкладывает только один человек у нас
карма: 27
0
Ответов: 9906
Рейтинг: 351
#6: 2009-04-28 19:38:09 ЛС | профиль | цитата
А еще неплохо БЫ сделать рисование, как положено в винде - по WM_PAINT, а не "по таймеру на хэндле".
Invalidate может ведь не только по KOL-овским onMouseEnter/Leave прилететь...
Винда его имеет право прислать в любой момент, никого не спрашивая.

Таская, например, чего ни то перед мордой примеров из папки OpenGL - можно спокойно наблюдать артефакты
По той же самой причине... Чем медленней таймер, тем заметнее артефакты.
карма: 9

0
Ответов: 1304
Рейтинг: 405
#7: 2009-04-28 21:35:40 ЛС | профиль | цитата
dynamic-95-188-164-72.ppp, в пору когда разбирался с основами OpenGL, возникала попытка завести тему где каждый мог-бы выложить простые схемы с пошаговым описанием. Но увы проект зачах, кто-то кого-то непонял .
http://hiasm.1gb.ru/forum.html?q=3&p=91935
Galkov, если можно ещё пару слов в чём выражен артефакт? уж чего я по экрану не таскал .
Единствено что заметил это срезание картинки.

Add(MainForm,15261923,203,112)
{
Left=20
Top=105
Width=440
Height=421
Point(MouseX)
Point(MouseY)
Point(Handle)
Point(onMouseMove)
Point(onMouseUp)
}
Add(GL_Main,12986311,217,175)
{
link(Handle,15261923:Handle,[])
}
Add(Hub,16299401,182,175)
{
OutCount=3
link(onEvent1,12986311:doInit,[])
link(onEvent2,12986311:doViewPort,[])
link(onEvent3,12986311:doFlip,[])
}
Add(Button,3133700,133,175)
{
Left=5
Top=10
Width=120
Caption="Отрисовать"
link(onClick,16299401:doEvent1,[])
}
карма: 3

0
Администрация
Ответов: 15295
Рейтинг: 1519
#8: 2009-04-29 00:00:10 ЛС | профиль | цитата
MAV, артефакт выражается в том, что WM_PAINT системный и Flip от OpenGL рассинхронизорованны и поэтому при некоторых обстоятельвах может быть заметно мигание. Однако... прошу заметить, что если в кодах библиотеки KOL есть методы, которые вызывают Invalidate элемента с перезаливкой фона (onMouseEnter/Leave именно этим и балуются), то исправить этот момент не возможно никак кроме перекрытия WM_ERASEBACKGROUND (вроде так сообщение звучит), что вообще говоря есть костыль.

Вот простой пример такого гадского Invalidate
code_13063.txt

однако если переписать RedrawManager вот так

#pas
procedure THIRedrawManager._work_doRedraw;
begin
InvalidateRect(_prop_ControlManager.ctrlpoint.Handle, nil, false);
end;
мы получим как раз то, что нужно

Galkov писал(а):
Винда его имеет право прислать в любой момент, никого не спрашивая.

насколько мне известно от системы никогда не приходят сообщения с требованием перерисовать фон, кроме как при изменении габаритных размеров окна. В этих случаях любое приложение будет мигать, что прекрасно видно на игре(под DirectX или OpenGL не важно) свернутой в оконный режим
карма: 27
0
файлы: 1code_13063.txt [609B] [247]
Ответов: 9906
Рейтинг: 351
#9: 2009-04-29 07:14:46 ЛС | профиль | цитата
Не только. На топе может быть не только наша форма. Манипуляции с другой формой (обозначенные ранее как "таскание чего ни то перед мордой") вызывают поток рисовательных событий и на нашей. Которые мы (по всем правилам) обязаны правильно отработать, не взирая на состояние нашего таймера.

Но даже не в этом дело.
Есть правило в винде: ты обязан быть готов в любую секунду нарисовать то, чего там должно быть на самом деле.
Костыльное оно или нет, а ничего тут уж не поделаешь.
Если мы научим пользователя следовать этому правилу, то остальная ответственность за качество рисования - уже за виндой.
Если научим нарушать - это будет не очень правильно.
Независимо от того, хотят пользователи, чтобы об них заботились, или не хотят, а заботиться - следует (некоторым и так не дует).

Есть вещи, которых я не знаю. К таковым относятся, например, OpenGL. Остается ли после flip-а "в запасном буфере" то, чего было ранее, или его надо творить заново - не знаю.
Но то, что знаю - знаю надежно.
Правильно (это то, что я знаю надежно) - по таймеру (или по другим интерфейсным событиям) менять рисунок OpenGL-модели в буфере, и делать invalidate (не важно в каком порядке, естественно). А по WM_PAINT (который является следствием не только нашего invalidate) кидать содержимое буфера "на показ".
И с WM_ERASEBKGND наша обязанность разобраться, если хотим рисовать на форме, а не на панели (у класса BUTTON в default-е оно ничего не делает)
Хоть костыль, хоть нет, а деваться некуда. Можно всю винду назвать одним большим костылем, если уж очень сильно призадуматься.

Скажем, то "баловство" Кладова с onMouseEnter/Leave
Не тот он человек, чтобы без причин лишние коды ставить. Следовательно, причины были. И достаточно серьезные, даже если мы о них и не знаем - "на всякий случай" он ничего не делает.
Я в деталях очень-то не разбирался, но оценил возможность доказать ему, что он дурак -- как совершенно бесперспективную. Потому-что он не дурак, и "правила рисования" не хуже нашего знает.

Да, были, когда-то, подмигивания при MainForm.Picture<>0. Этот вопрос (в отличие от OpenGL) я знаю, и поэтому этой проблемы просто нет. Давно уже.
карма: 9

0
Администрация
Ответов: 15295
Рейтинг: 1519
#10: 2009-04-29 12:06:10 ЛС | профиль | цитата
ну так предложенный выше пример как раз и реагирует на любые перерисовки из вне.
карма: 27
0
Ответов: 2125
Рейтинг: 159
#11: 2009-04-29 15:00:37 ЛС | профиль | цитата
Dilma писал(а):
никогда не приходят сообщения с требованием перерисовать фон, кроме как при изменении габаритных размеров окна

Неправда. Система всегда посылает сначала WM_ERASEBKGND, а потом уже WM_PAINT. Многие программы, чтобы не мигать, делают всю отрисовку по WM_ERASEBKGND, а на WM_PAINT плюют, т.к. последний может быть послан гораздо позже, чем обнаружилась необходимость перерисовки (когда процессор сильно загружен, винды не торопятся делать WM_PAINT).
карма: 1

0
Администрация
Ответов: 15295
Рейтинг: 1519
#12: 2009-04-29 15:25:57 ЛС | профиль | цитата
это поведение настраивается флагами при создании окна. Вот небольшая статейка по этому вопросу
http://www.delphisources.ru/pages/faq/base/drawing_without_twinkling.html
карма: 27
0
Ответов: 2125
Рейтинг: 159
#13: 2009-04-29 19:43:40 ЛС | профиль | цитата
Dilma писал(а):
это поведение настраивается флагами при создании окна

Ну да, если указать WS_EX_TRANSPARENT, то WM_ERASEBKGND посылаться не будет, НО! будет отрисовано содержимое под окном.
карма: 1

0
Ответов: 9906
Рейтинг: 351
#14: 2009-04-29 20:50:38 ЛС | профиль | цитата
tsdima, ну а если все-таки ближе к телу (как говаривал Мопосан)

Есть сегодня элементная база на OpenGL
Она предполагает получение хэндла от некого окна. Ничего не предполагая он его стилях, и т.п..
Какие есть варианты:
1) Если изменить эту постановку, то будут проблемы совместимости.
2) Можно делать хук через Set/GetWindowLong. Тогда, на какое сообщение садиться, или на оба - просто мелкие технические подробности.
3) Можно ничего не делать.

Ну вот и скажи мне как гинеколог гинекологу: какой вариант тебе больше по душе. И есть еще какой другой вариант
карма: 9

0
Ответов: 2125
Рейтинг: 159
#15: 2009-04-29 23:24:24 ЛС | профиль | цитата
Мне, как гинекологу, всё равно, т.к. я этим пока не пользуюсь. Учитывая, что большинство OpenGL программ обновляют окно 50 раз в секунду, можно ничего не делать. Если делать хук, то достаточно перехватывать WM_ERASEBKGND (или WM_PAINT если у окна стоит стиль WS_EX_TRANSPARENT). А Redraw делать как обычно, не отменяя WM_ERASEBKGND.
карма: 1

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)