HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- OpenGL (https://hlfx.ru/forum/forumdisplay.php?forumid=7)
-- Быстрый прямоугольник выделения (https://hlfx.ru/forum/showthread.php?threadid=4694)
Отправлено Garux 04-12-2015 в 09:00:
Быстрый прямоугольник выделения
Задача рисовать прямоугольник выделения без ререндера сцены.
Рисую с glBlendFunc( GL_ONE_MINUS_DST_COLOR, GL_ZERO );
Потом swap_buffers; И даже рисуется
Но только на winXP, т.к. там почему-то в GL_BACK автоматически оказывается содержимое GL_FRONT.
Попробовал скопировать так:
glReadBuffer( GL_FRONT );
glDrawBuffer( GL_BACK );
glRasterPos2i( 0, 0 );
glCopyPixels( 0, 0, width, height, GL_COLOR );
На XP остаётся пиксельная грязь, на виндах поновей - порядок.
Хотелось бы нормальное решение от знатоков.
Отправлено XaeroX 04-12-2015 в 09:08:
Зависит от места, в котором ты вызываешь отрисовку.
Ну вот так например попробуй (если после свапбуфферс основного рисования):
glDrawBuffer( GL_FRONT );
// рисуем
glDrawBuffer( GL_BACK );
Отправлено Garux 04-12-2015 в 11:03:
Ништяк, работает
Место там, где всё отрисовано и будет перерисовываться ещё не скоро.
Многократно рисуется/затирается прямоугольник выделения.
Отправлено Garux 02-01-2017 в 09:22:
Долго я радовался этому хаку (хотя на opengl.org указан как легит путь), но таки обнаружилась небольшая проблема: на некоторых системах ничего из нарисованного во фронт буффер не отображается при включённом MSAA.
Было примерно так:
C++ Source Code:
2 | glDrawBuffer( GL_FRONT ); |
4 | glDrawBuffer( GL_BACK ); |
5 | wglMakeCurrent //<-без этого следующие нормальные отрисовки со свопбуфферс визуально отстают на фрейм |
Поэтому решил попробовать схоронять статичный отрендеренный кусок в текстуру и потом поверх рисовать всякие гуёвые динамические штуки (ну и чтоб цветами можно было рисовать):
C++ Source Code:
4 | glGenTextures( 1, &m_rendered_tex ); |
6 | glBindTexture( GL_TEXTURE_2D, m_rendered_tex ); |
7 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
8 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
9 | glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 0, 0, width, height, 0 ); |
10 | glBindTexture( GL_TEXTURE_2D, 0 ); |
Потом ленивое гуи:
C++ Source Code:
2 | glEnable( GL_TEXTURE_2D ); |
4 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
5 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
6 | glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); |
7 | glBindTexture( GL_TEXTURE_2D, m_rendered_tex ); |
С этим вариантом две незадачи:
1. С MSAA сохранённая текстура выглядит как сумма семплов (линии жирные)
2. Другие огл окна в приложении заметно теряют фпс
Например движение в камере = обновление лениво нарисованной иконки камеры на сетке; камера становится явно менее плавной из-за SwapBuffers в ленивой отрисовке
Если рисовать текстуру во фронт без свопа - плавность возвращается (и баг с неотрисовкой при MSAA, разумеется, тоже-)
Возможно есть более совершенные способы ленивой отрисовки без названных проблем?
Отправлено XaeroX 02-01-2017 в 10:11:
Попробуй рисовать в FBO с включённым MSAA. Затем блитти его с ресолвингом мультисэмплинга. При этом у самого контекста MSAA не включай.
__________________
Отправлено Garux 04-01-2017 в 17:00:
Удалось завести FBO (хвала Аллаху!)
Непонятное с блит с ресолвингом: во фронт, похоже, нельзя, в бэк можно, но тогда нужен свопбуферс (и, что характерно, при таком способе ресолвится)
Сделал блит из мультисэмплового FBO в простой с приколоченной текстурой и нарисовал её на кваде - получаются жирные линии хоть со свопбуферс, хоть без.
Пока идеи заканчиваются на возможно разных форматах colour attachment, то таки ж написано, что обои GL_RGB
Отправлено XaeroX 04-01-2017 в 17:43:
Цитата:
Garux писал:
во фронт, похоже, нельзя
Что во фронт нельзя? Нарисовать квад с текстурой заресолвленного фреймбуфера нельзя? С какого перепугу?
Цитата:
Garux писал:
в бэк можно, но тогда нужен свопбуферс
Он всегда нужен, если у тебя дабл-буферинг включен у контекста. Не вижу проблемы.
Цитата:
Garux писал:
получаются жирные линии хоть со свопбуферс, хоть без.
Какие именно жирные линии получаются? Ты же не рисуешь в MSAA-буфер рамку. Ты у контекста отключил MSAA?__________________
Отправлено Garux 05-01-2017 в 17:57:
Получилося!
блит + ресолв во фронт буфер:
C++ Source Code:
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mfbo_fb); |
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); |
glDrawBuffer( GL_FRONT ); |
glBlitFramebuffer(0, 0, Width, Height, 0, 0, Width, Height, GL_COLOR_BUFFER_BIT, GL_NEAREST); |
Цитата:
Что во фронт нельзя? Нарисовать квад с текстурой заресолвленного фреймбуфера нельзя? С какого перепугу?
Один FBO с GL_COLOR_ATTACHMENT0 Multisample Renderbuffer, другой с glFramebufferTexture2D
Из первого во второй блитится, но без ресолвинга, фиг знает почему
Это для самой сцены, в ней получаются жирные линии; У контекста MSAA выкл (можно и вкл, на картинку не влияет)
Цитата:
Он всегда нужен, если у тебя дабл-буферинг включен у контекста. Не вижу проблемы.
Да, я тупанул, основную сцену можно бы и со своп нарисовать; Так надёжнее будет, а то, зафорсив MSAA в настройках драйвера, можно получить шанс не увидеть весёлых картинок вовсе.
Рисование во фронт нужно для ленивого гуи, чтоб плавность не убить
Отправлено XaeroX 06-01-2017 в 05:57:
Цитата:
Garux писал:
Из первого во второй блитится, но без ресолвинга, фиг знает почему
Этого не может быть, если у тебя там не glTexImage2DMultisample. Разве что баг драйвера.__________________
Отправлено Garux 09-01-2017 в 12:45:
Я бы скорее поставил на поверхностное понимание api
На другой системе у человека тоже не ресолвится
Сделал через промежуточный FBO вместо текстуры, т.к. блит в главбуфер опасный (если через драйвер включён несовпадающий с моим MSAA, то блита не будет)
Так же не ресовится, моя не пони май
Код целиком такой:
C++ Source Code:
2 | glGenFramebuffers( 1, &m_fbo_fb ); |
3 | glBindFramebuffer( GL_FRAMEBUFFER, m_fbo_fb ); |
4 | glGenRenderbuffers( 1, &m_fbo_color ); |
5 | glBindRenderbuffer( GL_RENDERBUFFER, m_fbo_color ); |
6 | glRenderbufferStorage( GL_RENDERBUFFER, GL_RGB, m_nWidth, m_nHeight ); |
7 | glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_fbo_color ); |
9 | glGenFramebuffers( 1, &m_mfbo_fb ); |
10 | glBindFramebuffer( GL_FRAMEBUFFER, m_mfbo_fb ); |
13 | glGenRenderbuffers( 1, &m_mfbo_color ); |
14 | glBindRenderbuffer( GL_RENDERBUFFER, m_mfbo_color ); |
15 | glRenderbufferStorageMultisample( GL_RENDERBUFFER, 8, GL_RGB, m_nWidth, m_nHeight ); |
16 | glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_mfbo_color ); |
18 | checkFramebufferStatus(); |
20 | glBindFramebuffer( GL_FRAMEBUFFER, m_mfbo_fb ); |
22 | checkFramebufferStatus(); |
24 | //рисуем без depth test |
26 | glBindFramebuffer( GL_READ_FRAMEBUFFER, m_mfbo_fb ); |
27 | glBindFramebuffer( GL_DRAW_FRAMEBUFFER, m_fbo_fb ); |
28 | glBlitFramebuffer( 0, 0, m_nWidth, m_nHeight, 0, 0, m_nWidth, m_nHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST ); |
32 | glBindFramebuffer( GL_READ_FRAMEBUFFER, m_fbo_fb ); |
33 | glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ); |
34 | glDrawBuffer( GL_BACK ); |
36 | glBlitFramebuffer( 0, 0, m_nWidth, m_nHeight, 0, 0, m_nWidth, m_nHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST ); |
37 | glBindFramebuffer( GL_FRAMEBUFFER, 0 ); |