Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.03.2014, 15:28   #11
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

100 текстур - это круто, возможно чтоит присмотреться к теме array textures (многослойные текстуры).

(glScalef и glRotatef)
в принципе написать свой манагер матриц преобразования не так уж сложно, все что нужно так это перед отрисовкой инициалировать нужную юниформу шейдера (глобальную для шейдера константу) посчитанной матрицей преобразования.


про отрисовку в тектуру.
посмотрел свою писанину. когда-то развлекал себя на тему видео в огл, ничего умнее отрисовки в текстуру не придумал, получилась довольно простая (и слегка бесполезная мурзилка), но в качестве примера сойдет.

базовая идея:
существует несколько источников видео, каждому из источников присваивается слой многослойной текстуры. ключевой фрейм видео грузится с помощью TexSubImage3D, дельта фреймым отрисовываются шейдером.

Последний раз редактировалось f.hump; 29.03.2014 в 18:23.
f.hump вне форума Ответить с цитированием
Старый 29.03.2014, 15:33   #12
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

в теме участвуют два шейдера вершинный (vertex shader) и пиксельный (fragment shader)

vertex shader:
Код:
#version 330 core

layout(location = 0) in vec4 pixel_coords;
layout(location = 1) in vec4 delta_color;

flat out vec4 pi_color;
uniform vec4 coords_scale;

void main() {	
	gl_Position = vec4(-1.0, -1.0, 0.0, 0.0) + pixel_coords*coords_scale;
	pi_color = delta_color;
}
fragment shader:
Код:
#version 330 core

layout(location = 0) out vec4 f_color;

uniform sampler2DArray ms_texture;
uniform ivec4 local_config;

flat in vec4 pi_color;

void main() {
	f_color = pi_color + texelFetch(ms_texture, ivec3(gl_FragCoord.xy, local_config[0]), 0);
}
ничего умного они не делают, первый скалирует входящие координаты, второй добавляет входящий цветовой вектор к цвету выбранного слоя текстуры. слой определяется значением local_config[0].
f.hump вне форума Ответить с цитированием
Старый 29.03.2014, 15:40   #13
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

ЗЫ. в личных целях переписал стандартные огл хедеры, в большенстве случаев префикс OpenGL:: перед именем функции имеет смысл gl. опять же по личным причинам пользуюсь только core context, никакого compatibility context.

на стороне клиента происходит инициализация контекста:


Код:
int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 2, WGL_CONTEXT_PROFILE_MASK_ARB,  WGL_CONTEXT_CORE_PROFILE_BIT_ARB, WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, 0, 0};

	if (SetPixelFormat(w_hdc, OpenGL::Core::GetPFI(), OpenGL::Core::GetPFD())) {
		if (HGLRC gl_rc = WGL::CreateContextAttribs(w_hdc, 0, attribs)) {
			if (OpenGL::Core::ShareRC(gl_rc) == 0) {
				if (WGL::MakeContextCurrent(w_hdc, w_hdc, gl_rc)) {
							
					OpenGL::glViewport(0, 0, 1920, 1080);

					OpenGL::glDisable(GL_DEPTH_TEST);
					OpenGL::glDisable(GL_CULL_FACE);
					OpenGL::glDisable(GL_STENCIL_TEST);
					OpenGL::glDisable(GL_SCISSOR_TEST);									
					OpenGL::glDisable(GL_BLEND);
																																				
					OpenGL::GenVertexArrays(1, &_wao);
					OpenGL::BindVertexArray(_wao);

					OpenGL::GenBuffers(1, &_codo_buf);
					OpenGL::BindBuffer(GL_ARRAY_BUFFER, _codo_buf);
									
					OpenGL::ClampColor(GL_CLAMP_READ_COLOR, GL_FALSE);
									
					OpenGL::glPixelStorei(GL_PACK_ALIGNMENT, 4);
					OpenGL::glPixelStorei(GL_PACK_ROW_LENGTH, 0);
					OpenGL::glPixelStorei(GL_PACK_SKIP_ROWS, 0);
					OpenGL::glPixelStorei(GL_PACK_SKIP_PIXELS, 0);



					OpenGL::GenFramebuffers(1, &video_frame);

					OpenGL::BindFramebuffer(GL_DRAW_FRAMEBUFFER, video_frame);
					OpenGL::BindFramebuffer(GL_READ_FRAMEBUFFER, video_frame);

					OpenGL::ActiveTexture(GL_TEXTURE0);

					result = video_pass.Initialize();

					OpenGL::EnableVertexAttribArray(0);
					OpenGL::EnableVertexAttribArray(1);

					OpenGL::VertexAttribPointer(0, 2, GL_UNSIGNED_SHORT, GL_FALSE, 8, 0);
					OpenGL::VertexAttribPointer(1, 4, GL_BYTE, GL_TRUE, 8, (const void *)4);

.......
.......
для правильной инициализации в core context необходимо создать и привязать VertexArrayObject. в нем хранится текущая конфигурация вершинных аттрибутов (какие аттрибуты разрешены, с какими буферами связаны и т.п.). поскольку никаких альтернативных конфигураций в данной задаче не планировалось, был создан только один VAO (_wao).

Дальше был создан и привязан буффер в котором хранятся вершинные аттрибуты (_codo_buf).

Надо отметить, что тут были разрешены и сконфигурированны два массива, которые идут на вход вершинного шейдера (pixel_coords и delta_color). в целях личного удобства массивы сделанны iterleaved и хранятся в одном буфере (_codo_buf). первый массив - двух компонентные координаты пикселя (GL_UNSIGNED_SHORT на компоненту), втрой массив - четырехкомпонентные вектора коррекции цвета (GL_BYTE на компоненту)

Поскольку отрисовка пранировалась не в default buffer, был создан и привязан FrameBuffer (video_frame).

В принципе, после создания контекста текущий текстурный юнит это GL_TEXTURE0, но на всякий случай сделал ActiveTexture(GL_TEXTURE0). (текстурный юнит для текстур имеет такой же смысл как и VAO для аттрибутов: набор состояний и флагов (какой тип текстуры подлючен, имя текстуры и т.п.)

да, поскольку не хотелось, чтобы процесс обновления видео фреймов сильно сказывался на отрисовке в основном контексте, на который реагирует юзер, обновление видео фреймов происходит в отдельном потоке и соответственно в другом контексте. по умолчанию, если есть два огл контекста то они имеют назависимые пространства имен для текстур и буферов, т.е. нельзя обратиться к текстуре/буферу в одном контексте по ее/его имени из другого контекста. для обобщения пространства имен на два контекста была произведена операция шары OpenGL::Core::ShareRC(gl_rc), эта процедура делегирует вызов wglShareLists в основной поток, до того как gl_rc стал текущим для видео потока.

в video_pass.Initialize() происходит следующее
Код:
				program.VertexShader.FromResource(17404, libin);
				program.FragmentShader.FromResource(17405, libin);
		
				if (result = program.Build()) {
					local_cfg.location = OpenGL::GetUniformLocation(program.GetName(), "local_config");					

					ms_texture.location = OpenGL::GetUniformLocation(program.GetName(), "ms_texture");
					ms_texture.value.i_val = 0;

					coords_scale.location = OpenGL::GetUniformLocation(program.GetName(), "coords_scale");
					coords_scale.value[0].float_cmp = 2.0f/1920.0f; coords_scale.value[1].float_cmp = 2.0f/1080.0f; coords_scale.value[2].float_cmp = 1.0f; coords_scale.value[3].float_cmp = 1.0f;

					OpenGL::UseProgram(program.GetName());
					OpenGL::Uniform1i(ms_texture.location, ms_texture.value.i_val);
					OpenGL::Uniform4fv(coords_scale.location, 1, &coords_scale.value[0].float_cmp);

					result = OpenGL::glGetError();
				} else {
					result = 333333;
				}
имеет место загрузка кода шейдеров, компиляция, линковка и инициализация некоторых констант (юниформ).

Последний раз редактировалось f.hump; 29.03.2014 в 22:36.
f.hump вне форума Ответить с цитированием
Старый 29.03.2014, 15:46   #14
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

когда приходит время отрисовки происходит следующее:
Код:
	result = video_pass.InitRender(source_cfg->render_id, lid);
															
		if (!result)
		if (unsigned int * pipo = reinterpret_cast<unsigned int *>(source_cfg->frame_buf.Acquire())) {															
									
			if (pipo[0] == 0xFF101010) {
				if (pipo[1] == 0xFF101010) { // pipo[2] - forward/reverse
					area = source_cfg->width*source_cfg->height;
					if (unsigned int * x_ptr = reinterpret_cast<unsigned int *>(x_buffer.Acquire())) {
						if (pipo[2] == 0xFF101010) vcount = ScanRDFrame(x_ptr, pipo+source_cfg->c_width*source_cfg->c_height, source_cfg->height, source_cfg->width);
						else vcount = ScanFDFrame(x_ptr, pipo+source_cfg->c_width*source_cfg->c_height, area, source_cfg->width);

						OpenGL::BufferData(GL_ARRAY_BUFFER, vcount, x_ptr, GL_STREAM_DRAW);
						OpenGL::glDrawArrays(GL_POINTS, 0, vcount>>3);

						result = OpenGL::glGetError();
						x_buffer.Release();
					}
			} else {
			}
		} else {
			OpenGL::TexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, lid, source_cfg->c_width, source_cfg->c_height, 1, GL_RGBA, GL_UNSIGNED_BYTE, pipo); // 
			result = OpenGL::glGetError();
		}
как и отметил раньше, ключевые фреймы идут в TexSubImage3D, остальные проходят через glDrawArrays.

Последний раз редактировалось f.hump; 29.03.2014 в 16:04.
f.hump вне форума Ответить с цитированием
Старый 29.03.2014, 15:58   #15
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

Код:
		size_t InitRender(unsigned int rid, unsigned int & lid) {
			size_t result(0);
			
			local_cfg.value[0].i_cmp = local_cfg.value[1].i_cmp = local_cfg.value[2].i_cmp = local_cfg.value[3].i_cmp = 0;

			if (StreamRecord * smap = reinterpret_cast<StreamRecord *>(slot_map.Acquire())) {
				
				OpenGL::glBindTexture(GL_TEXTURE_2D_ARRAY, smap[rid].tex_id);				
				
				OpenGL::FramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, smap[rid].tex_id, 0, smap[rid].layer_id);
				if (OpenGL::CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) result = OpenGL::glGetError();
					
				local_cfg.value[0].i_cmp = smap[rid].layer_id;
				lid = smap[rid].layer_id;
				if (local_cfg.location != -1) OpenGL::Uniform4iv(local_cfg.location, 1, &local_cfg.value[0].i_cmp);			
				

				slot_map.Release();
			}

			return result;
		}
video_pass.InitRender собственно связывает текущий фреймбуфер со слоем текстуры и устанавливает значение local_config для fragment shader.

вообщем и все. видео действительно рисуется, но по ходу обнаружилось, что отрисовка происходит более эффективно, когда дельта фреймы добавляются на CPU и результат копируется с помощью TexSubImage3D.
f.hump вне форума Ответить с цитированием
Старый 29.03.2014, 22:19   #16
Shkolota
Пользователь
 
Регистрация: 02.04.2013
Сообщений: 51
По умолчанию

Всем спасибо за советы. Появился еще такой вопрос. Использую Framebuffer'ы (glGenFrameBuffersEXT) для рисования в текстуру. К буферу присоединена текстура. При установке формата пикселя, когда создаю основной контекст воспроизведения, то задаю ему:

Код:
gluOrtho2D(-1, 1, -1, 1);
Далее - создаю и активирую Framebuffer. После этого - устанавливаю для него:

Код:
gluOrtho2D(0, Width, 0, Height);
Но такое ощущение, что gluOrtho2D задается для основного контекста. Идея в следующем: установить системы координат таким образом, чтобы для FrameBuffer'а система была задана в оконном формате, и объекты рисоваться на нем могли по своим настоящим координатам. Для основного контекста же система задавалась бы в формате OpenGL (-1..1), и при перерисовке FrameBuffer'а на экран использовалась бы такая сетка.

Признаюсь, что такой алгоритм придуман в угоду работе с шейдерами, так как, насколько я понял, они работают только с OpenGL'овской системой, но объекты, которые я рисую, имеют оконные координаты. Переводить каждую координату в OpenGL'овскую было бы долго.
Shkolota вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Шейдеры в OpenGL для начинающих. _PROGRAMM_ Gamedev - cоздание игр: Unity, OpenGL, DirectX 12 21.12.2020 23:43
шейдеры ser70 Общие вопросы C/C++ 2 05.11.2014 09:54
Шейдеры Inv1s Gamedev - cоздание игр: Unity, OpenGL, DirectX 3 28.06.2012 13:46
Шейдеры (HLSL) и OpenGL ImmortalAlexSan Gamedev - cоздание игр: Unity, OpenGL, DirectX 3 11.04.2012 18:54
Шейдеры _-Re@l-_ Gamedev - cоздание игр: Unity, OpenGL, DirectX 7 01.08.2010 14:33