OpenGL: отображение JPEG

Модератор: Модераторы разделов

IMB
Сообщения: 2567
ОС: Debian

OpenGL: отображение JPEG

Сообщение IMB »

Доброго дня!
В программе написанной с использованием Qt необходимо отображать JPEG с IP-камеры, вариант с использованием QPixmap не подошёл в следствии большого расхода памяти.

Код: Выделить всё

QSize frame_resolution; //геометрические размеры
QByteArray jpg; //изображение

void Image::initializeGL()
{
    qglClearColor(Qt::black);
}

void Image::resizeGL(int width, int height)
{
    qDebug() << "run Image::resizeGL";
    glViewport(0, 0, width, height);
    qDebug() << "after glViewport" << glGetError();
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    qDebug() << "after glPixelStorei" << glGetError();
    glPixelZoom(1, 1);
    qDebug() << "after glPixelZoom" << glGetError();
    glMatrixMode(GL_PROJECTION);
    qDebug() << "after glMatrixMode" << glGetError();
    glLoadIdentity();
    qDebug() << "after glLoadIdentity" << glGetError();
    glViewport(0, 0, width, height);
    qDebug() << "after glViewport" << glGetError();
    qDebug() << "end Image::resizeGL";
}

void Image::paintGL()
{
    qDebug() << "runImage::paintGL"
             << frame_resolution.width()
                << frame_resolution.height()
                   << jpg.size() << frame_part;
    /*QImage image;
    image.loadFromData(jpg);
    QImage img = QGLWidget::convertToGLFormat(image);*/
    glDrawPixels(frame_resolution.width(), frame_resolution.height(), GL_RGB,
                 GL_UNSIGNED_BYTE, jpg.data());
    qDebug() << "after glDrawPixels" << glGetError();
    qDebug() << "end Image::paintGL" << glGetError();
}

Вывод в консоль:

Код: Выделить всё

run Image::view_image
run Image::resizeGL
after glViewport 0
after glPixelStorei 0
after glPixelZoom 0
after glMatrixMode 0
after glLoadIdentity 0
after glViewport 0
end Image::resizeGL
runImage::paintGL 800 592 1296 21
after glDrawPixels 0
end Image::paintGL 0

Насколько я могу понять ошибок нет, но окно с изображением не появляется, более того - окно вообще не появляется.
Основной вопрос - почему не появляется окно с чёрным фоном, которым я инициализировал?
Спасибо.

P.S. Данный по проверке OpenGL

Код: Выделить всё

$ glxgears
3324 frames in 5.0 seconds = 661.961 FPS
3420 frames in 5.0 seconds = 681.951 FPS

Код: Выделить всё

$ glxinfo
name of display: :0.0
display: :0  screen: 0
direct rendering: No (If you want to find out why, try setting LIBGL_DEBUG=verbose)
server glx vendor string: SGI
server glx version string: 1.2
server glx extensions:
    GLX_ARB_multisample, GLX_EXT_visual_info, GLX_EXT_visual_rating,
    GLX_EXT_import_context, GLX_EXT_texture_from_pixmap, GLX_OML_swap_method,
    GLX_SGI_make_current_read, GLX_SGIS_multisample, GLX_SGIX_hyperpipe,
    GLX_SGIX_swap_barrier, GLX_SGIX_fbconfig, GLX_MESA_copy_sub_buffer
client glx vendor string: Mesa Project and SGI
client glx version string: 1.4
client glx extensions:
    GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_EXT_import_context,
    GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_MESA_allocate_memory,
    GLX_MESA_copy_sub_buffer, GLX_MESA_swap_control,
    GLX_MESA_swap_frame_usage, GLX_OML_swap_method, GLX_OML_sync_control,
    GLX_SGI_make_current_read, GLX_SGI_swap_control, GLX_SGI_video_sync,
    GLX_SGIS_multisample, GLX_SGIX_fbconfig, GLX_SGIX_pbuffer,
    GLX_SGIX_visual_select_group, GLX_EXT_texture_from_pixmap
GLX version: 1.2
GLX extensions:
    GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_EXT_import_context,
    GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_MESA_copy_sub_buffer,
    GLX_OML_swap_method, GLX_SGI_make_current_read, GLX_SGIS_multisample,
    GLX_SGIX_fbconfig, GLX_EXT_texture_from_pixmap
OpenGL vendor string: Mesa project: www.mesa3d.org
OpenGL renderer string: Mesa GLX Indirect
OpenGL version string: 1.4 (2.1 Mesa 7.0.4)
OpenGL extensions:
GL_ARB_depth_texture, GL_ARB_draw_buffers, GL_ARB_fragment_program,
    GL_ARB_imaging, GL_ARB_multisample, GL_ARB_multitexture,
    GL_ARB_occlusion_query, GL_ARB_point_parameters, GL_ARB_point_sprite,
    GL_ARB_shadow, GL_ARB_shadow_ambient, GL_ARB_texture_border_clamp,
    GL_ARB_texture_compression, GL_ARB_texture_cube_map,
    GL_ARB_texture_env_add, GL_ARB_texture_env_combine,
    GL_ARB_texture_env_crossbar, GL_ARB_texture_env_dot3,
    GL_ARB_texture_mirrored_repeat, GL_ARB_texture_non_power_of_two,
    GL_ARB_texture_rectangle, GL_ARB_transpose_matrix, GL_ARB_vertex_program,
    GL_ARB_window_pos, GL_EXT_abgr, GL_EXT_bgra, GL_EXT_blend_color,
    GL_EXT_blend_equation_separate, GL_EXT_blend_func_separate,
    GL_EXT_blend_logic_op, GL_EXT_blend_minmax, GL_EXT_blend_subtract,
    GL_EXT_clip_volume_hint, GL_EXT_copy_texture, GL_EXT_draw_range_elements,
    GL_EXT_fog_coord, GL_EXT_framebuffer_object, GL_EXT_multi_draw_arrays,
    GL_EXT_packed_pixels, GL_EXT_paletted_texture, GL_EXT_point_parameters,
    GL_EXT_polygon_offset, GL_EXT_rescale_normal, GL_EXT_secondary_color,
    GL_EXT_separate_specular_color, GL_EXT_shadow_funcs,
    GL_EXT_shared_texture_palette, GL_EXT_stencil_wrap, GL_EXT_subtexture,
    GL_EXT_texture, GL_EXT_texture3D, GL_EXT_texture_edge_clamp,
    GL_EXT_texture_env_add, GL_EXT_texture_env_combine,
    GL_EXT_texture_env_dot3, GL_EXT_texture_lod_bias,
    GL_EXT_texture_mirror_clamp, GL_EXT_texture_object,
    GL_EXT_texture_rectangle, GL_EXT_vertex_array, GL_APPLE_packed_pixels,
    GL_ATI_draw_buffers, GL_ATI_texture_env_combine3,
    GL_ATI_texture_mirror_once, GL_ATIX_texture_env_combine3,
    GL_IBM_texture_mirrored_repeat, GL_INGR_blend_func_separate,
    GL_MESA_pack_invert, GL_MESA_ycbcr_texture, GL_NV_blend_square,
    GL_NV_fragment_program, GL_NV_light_max_exponent, GL_NV_point_sprite,
    GL_NV_texgen_reflection, GL_NV_texture_rectangle, GL_NV_vertex_program,
    GL_NV_vertex_program1_1, GL_SGI_color_matrix, GL_SGI_color_table,
    GL_SGIS_generate_mipmap, GL_SGIS_texture_border_clamp,
    GL_SGIS_texture_edge_clamp, GL_SGIS_texture_lod, GL_SGIX_depth_texture,
    GL_SGIX_shadow, GL_SGIX_shadow_ambient, GL_SUN_multi_draw_arrays

5 GLX Visuals
 visual  x  bf lv rg d st colorbuffer ax dp st accumbuffer  ms  cav
 id dep cl sp sz l  ci b ro  r  g  b  a bf th cl  r  g  b  a ns b eat
----------------------------------------------------------------------
0x22 24 tc  0 24  0 r  y  .  8  8  8  0  0 16  0  0  0  0  0  0 0 None
0x23 24 tc  0 24  0 r  y  .  8  8  8  0  0 16  8 16 16 16  0  0 0 None
0x24 24 tc  0 32  0 r  y  .  8  8  8  8  0 16  8 16 16 16 16  0 0 None
0x25 24 tc  0 32  0 r  .  .  8  8  8  8  0 16  8 16 16 16 16  0 0 None
0x3e 32 tc  0 32  0 r  .  .  8  8  8  8  0  0  0  0  0  0  0  0 0 Ncon

5 GLXFBConfigs:
   visual  x  bf lv rg d st colorbuffer ax dp st accumbuffer  ms  cav
 id dep cl sp sz l  ci b ro  r  g  b  a bf th cl  r  g  b  a ns b eat
----------------------------------------------------------------------
0x22  0 tc  0 24  0 r  y  .  8  8  8  0  0 16  0  0  0  0  0  0 0 None
0x23  0 tc  0 24  0 r  y  .  8  8  8  0  0 16  8 16 16 16  0  0 0 None
0x24  0 tc  0 32  0 r  y  .  8  8  8  8  0 16  8 16 16 16 16  0 0 None
0x25  0 tc  0 32  0 r  .  .  8  8  8  8  0 16  8 16 16 16 16  0 0 None
0x3e  0 tc  0 32  0 r  .  .  8  8  8  8  0  0  0  0  0  0  0  0 0 Ncon
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

С необотображением окна разобрался:

Код: Выделить всё

void Image::paintGL()
{
.......................
show();
}

Буду разбираться с отображением изображения.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: OpenGL: отображение JPEG

Сообщение eddy »

IMB писал(а):
19.07.2011 10:06
Буду разбираться с отображением изображения.

Так там же несложно: "запихиваете" изображение в текстуру, которую "натягиваете" на прямоугольник. Может, поможет (но там на С).

Кстати, у вас direct rendering == NO! И почему-то вместо нормального openGL используется дурацкая MESA.

Настройте для начала видеокарту, а то тормозить будет невменяемо.
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

eddy писал(а):
19.07.2011 10:37
Кстати, у вас direct rendering == NO! И почему-то вместо нормального openGL используется дурацкая MESA.
Настройте для начала видеокарту, а то тормозить будет невменяемо.

Да и ладно, мне бы сейчас просто вывести изображение. Со скоростью буду разбираться потом.
eddy, я так понял, что без декодирования JPG ничего работать не будет?
Вот ещё наткнулся на обсуждение этого вопроса http://www.linux.org.ru/forum/development/5155189
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: OpenGL: отображение JPEG

Сообщение eddy »

IMB писал(а):
19.07.2011 10:56
без декодирования JPG ничего работать не будет?

Конечно, не будет. Просто подключите libjpeg, либо libffmpeg, либо libgd, либо что-то еще. Кстати, можно и с LD_PRELOAD запустить (по идее, тогда не надо будет декодировать - но у меня получалось вверх ногами, поэтому пришлось все делать самому). Но можете по ссылочке глянуть код для получения картинки с камеры и ее отображения, там ничего сложного нет (v4l2 + libjpeg + openGL).
IMB писал(а):
19.07.2011 10:56
Вот ещё наткнулся на обсуждение этого вопроса http://www.linux.org.ru/forum/development/5155189

Я - ТС :)
И, кстати, тема - как раз о том, что я вам по ссылочке выложил.
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

Чего то не понимаю в работе с текстурами.
инициализация

Код: Выделить всё

void Image::initializeGL()
{
    qglClearColor(Qt::black);
    glGenTextures(1, &id);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, id);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}

измение размера

Код: Выделить всё

void Image::resizeGL(int width, int height)
{
    qDebug() << "run Image::resizeGL";
    glPixelZoom(1, 1);
    qDebug() << "after glPixelZoom" << glGetError();
    glViewport(0, 0, width, height);
    qDebug() << "after glViewport" << glGetError();
    glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA, width, height, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, 0);
    qDebug() << "after glTexImage2D" << glGetError();
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA,
                    GL_UNSIGNED_BYTE, jpg.data());
    qDebug() << "after glTexSubImage2D" << glGetError();
    qDebug() << "end Image::resizeGL";
}

Если я в glTexSubImage2D передаю NULL, как указатель на данные, то получаю следующее сообщение:

Код: Выделить всё

X Error: BadLength (poly request too large or internal Xlib length error) 16
  Extension:    158 (Uknown extension)
  Minor opcode: 1 (Unknown request)
  Resource id:  0x2e0019b

При передаче указателя на данные, получаю функцией QByteArray data(), программа вылетает с Segmentation fault.
Программу запускаю следующим образом LD_PRELOAD=/usr/lib/libjpeg.so.8 LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./qtclient
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

И ещё вопрос - наткнулся на замечание, что размеры текстуры должны быть кратные 2, что в моём случае совсем не гарантируется.
OpenGL перестанет работать в этом случае или работа замедлится?
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: OpenGL: отображение JPEG

Сообщение eddy »

IMB писал(а):
19.07.2011 12:09
И ещё вопрос - наткнулся на замечание, что размеры текстуры должны быть кратные 2, что в моём случае совсем не гарантируется.
OpenGL перестанет работать в этом случае или работа замедлится?

Я работал с текстурами произвольных размеров. Скорость падает незначительно (а может, и вовсе не падает).

IMB писал(а):
19.07.2011 11:56
Программу запускаю следующим образом LD_PRELOAD=/usr/lib/libjpeg.so.8 LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./qtclient

А зачем jpeg-библиотеку в LD_PRELOAD?

Кстати, у вас проблемка с openGL'ем может быть из-за того, что вы не вставили код инициализации. Например, в GTK все openGL'ные функции надо вставлять в "блоки"

Код: Выделить всё

gdk_gl_drawable_gl_begin(glDrawable, glContext)
...
gdk_gl_drawable_gl_end(glDrawable);

иначе ничего не работает.

Может, в кутях так же?
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

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

Код: Выделить всё

QImage Image::convert_to_GL(const QByteArray &data)
{
    QImage image = QImage::fromData(data);

    return QGLWidget::convertToGLFormat(image);
}

По таймеру от начала получения до отображения проходит ~100 мс, а картинка не обновляется, возможно это связано с direct rendering.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

Мда, странно как то nvidia сработала. Стоит nVidia Corporation NV34 [GeForce FX 5500] (rev a1),
Поставил драйвера NVidia:

Код: Выделить всё

libgl1-nvidia-alternatives      195.36.31-6
libgl1-nvidia-legacy-173xx-glx  173.14.27-2
libglx-nvidia-alternatives      195.36.31-6
nvidia-glx-legacy-173xx 173.14.27-2
nvidia-kernel-common    20100522+1
nvidia-kernel-legacy-173xx-dkms 173.14.27-2
nvidia-settings 195.36.24-1
nvidia-xconfig  195.36.31-1

Модуль nvidia загружен, но...

Код: Выделить всё

$ glxinfo
name of display: :0.0
display: :0  screen: 0
direct rendering: Yes
server glx vendor string: NVIDIA Corporation
server glx version string: 1.4
server glx extensions:
    GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_SGIX_fbconfig,
    GLX_SGIX_pbuffer, GLX_SGI_video_sync, GLX_SGI_swap_control,
    GLX_EXT_texture_from_pixmap, GLX_ARB_multisample, GLX_NV_float_buffer
client glx vendor string: NVIDIA Corporation
client glx version string: 1.4
client glx extensions:
    GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_EXT_visual_info,
    GLX_EXT_visual_rating, GLX_EXT_import_context, GLX_SGI_video_sync,
    GLX_NV_swap_group, GLX_NV_video_out, GLX_SGIX_fbconfig, GLX_SGIX_pbuffer,
    GLX_SGI_swap_control, GLX_NV_float_buffer, GLX_ARB_fbconfig_float,
    GLX_EXT_fbconfig_packed_float, GLX_EXT_texture_from_pixmap,
    GLX_EXT_framebuffer_sRGB, GLX_NV_present_video
GLX version: 1.3
GLX extensions:
    GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_SGIX_fbconfig,
    GLX_SGIX_pbuffer, GLX_SGI_video_sync, GLX_SGI_swap_control,
    GLX_EXT_texture_from_pixmap, GLX_ARB_multisample, GLX_NV_float_buffer,
    GLX_ARB_get_proc_address
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: GeForce FX 5500/AGP/SSE2
OpenGL version string: 2.1.2 NVIDIA 173.14.27
OpenGL shading language version string: 1.20 NVIDIA via Cg compiler
...............

Код: Выделить всё

$ glxgears
Running synchronized to the vertical refresh.  The framerate should be
approximately the same as the monitor refresh rate.
303 frames in 5.0 seconds = 60.496 FPS
301 frames in 5.0 seconds = 60.023 FPS
301 frames in 5.0 seconds = 60.022 FPS

Получается, что в тесте glxgears производительность упала в 10 раз!
Ну и приятный бонус - шрифт интерфейсов стал нечитабельным из за мелкого размера.
/etc/X11/xorg.conf

Код: Выделить всё

Section "ServerLayout"
    Identifier     "Default Layout"
    Screen         "Default Screen" 0 0
    InputDevice    "Generic Keyboard"
    InputDevice    "Configured Mouse"
EndSection

Section "Module"

#       Load    "dri"
    Load           "bitmap"
#       Load    "ddc"
    Load           "extmod"
    Load           "freetype"
    Load           "glx"
    Load           "int10"
    Load           "vbe"
EndSection

Section "InputDevice"
    Identifier     "Generic Keyboard"
    Driver         "kbd"
    Option         "CoreKeyboard"
    Option         "XkbRules" "xorg"
    Option         "XkbModel" "pc105"
    Option         "XkbLayout" "us,ru"
    Option         "XkbVariant" ",winkeys"
        Option          "XkbOptions"    "grp:ctrl_shift_toggle,grp_led:scroll"
    #Option         "XkbOptions" "grp:lwin_toggle,grp_led:scroll"
EndSection

Section "InputDevice"
    Identifier     "Configured Mouse"
    Driver         "mouse"
    Option         "CorePointer"
    Option         "Device" "/dev/input/mice"
    Option         "Protocol" "ImPS/2"
    Option         "Emulate3Buttons" "true"
EndSection

Section "Monitor"
    Identifier     "Samsung SyncMaster940N"
 HorizSync       30.0 - 65.0
    VertRefresh     50.0 - 75.0
    Option         "DPMS"
EndSection

Section "Device"

#       Driver          "nv"
    Identifier     "GeForce FX 5500"
    Driver         "nvidia"
EndSection

Section "Screen"
    Identifier     "Default Screen"
    Device         "GeForce FX 5500"
    Monitor        "Samsung SyncMaster940N"
    DefaultDepth    24
    SubSection     "Display"
        Depth       1
        Modes      "1280x1024" "1280x960" "1280x854" "1280x800" "1280x768" "1200x800" "1152x864" "1152x768" "1024x768" "800x600" "640x480"
    EndSubSection
    SubSection     "Display"
        Depth       4
        Modes      "1280x1024" "1280x960" "1280x854" "1280x800" "1280x768" "1200x800" "1152x864" "1152x768" "1024x768" "800x600" "640x480"
    EndSubSection
    SubSection     "Display"
        Depth       8
        Modes      "1280x1024" "1280x960" "1280x854" "1280x800" "1280x768" "1200x800" "1152x864" "1152x768" "1024x768" "800x600" "640x480"
    EndSubSection
    SubSection     "Display"
        Depth       15
        Modes      "1280x1024" "1280x960" "1280x854" "1280x800" "1280x768" "1200x800" "1152x864" "1152x768" "1024x768" "800x600" "640x480"
    EndSubSection
    SubSection     "Display"
        Depth       16
        Modes      "1280x1024" "1280x960" "1280x854" "1280x800" "1280x768" "1200x800" "1152x864
" "1152x768" "1024x768" "800x600" "640x480"
    EndSubSection
    SubSection     "Display"
        Depth       24
        Modes      "1280x1024" "1280x960" "1280x854" "1280x800" "1280x768" "1200x800" "1152x864" "1152x768" "1024x768" "800x600" "640x480"
    EndSubSection
EndSection



Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: OpenGL: отображение JPEG

Сообщение eddy »

IMB писал(а):
19.07.2011 16:05
Получается, что в тесте glxgears производительность упала в 10 раз!

Читайте внимательнее:
Running synchronized to the vertical refresh. The framerate should be
approximately the same as the monitor refresh rate.

RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

Малый размер шрифта победил прописав установку DPI в xorg.conf.
Производительность в glxgears зависит от OpenGL Settings/Sync to VBlank, при установленном 60 FPS, в противном случае 3440 FPS.
Вот только на выводе JPEG это сказалось в худшую строну - теперь вывод первого кадра присходит через 16000 мс, буду разбираться.
Работа с OpenGL:

Код: Выделить всё

QGLFormat glformat;
//проверяю поддержку OpenGL в конструкторе
if (glformat.hasOpenGL()) {
        setFormat(QGLFormat(QGL::DirectRendering));
        initializeGL();
.............
}

void Image::initializeGL()
{
    qglClearColor(Qt::black);
    glGenTextures(1, &id);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, id);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}

void Image::resizeGL(int width, int height)
{
    glPixelZoom(1, 1);
    glViewport(0, 0, width, height);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA, width, height, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, 0);
    img = convert_to_GL(jpg);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA,
                    GL_UNSIGNED_BYTE, img.bits());
}

QImage Image::convert_to_GL(const QByteArray &data)
{
    QImage image = QImage::fromData(data);

    return QGLWidget::convertToGLFormat(image);
}

void Image::paintGL()
{

    glDrawPixels(frame_resolution.width(), frame_resolution.height(), GL_RGBA,
                 GL_UNSIGNED_BYTE, img.bits());
    if (GL_NO_ERROR == glGetError()) {
        setWindowTitle(QString("frame %1 %2x%3 in %4 ms, %5 FPS").
                       arg(frame_number).
                       arg(frame_resolution.width()).
                       arg(frame_resolution.height()).
                       arg(t.elapsed(), 0, 10).
                       arg(fps));
        show();
    }
}
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

Проблему со скорость вывода решил так:

Код: Выделить всё

void Image::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(0.0, 0.0, 0.0);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(0.0, frame_resolution.height(), 0.0);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(frame_resolution.width(), frame_resolution.height(), 0.0);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(frame_resolution.width(), 0.0, 0.0);
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glDrawPixels(frame_resolution.width(), frame_resolution.height(), GL_RGBA,
                 GL_UNSIGNED_BYTE, img.bits());
    if (GL_NO_ERROR == glGetError()) {
        setWindowTitle(QString("frame %1 %2x%3 in %4 ms, %5 FPS").
                       arg(frame_number).
                       arg(frame_resolution.width()).
                       arg(frame_resolution.height()).
                       arg(t.elapsed(), 0, 10).
                       arg(fps));
        show();
    }
}

Вот только картинка статична. Выглядит так, как будто отобразился первый кадр, а последующие хоть и приходят, видно по таймеру, но не отображаются.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: OpenGL: отображение JPEG

Сообщение eddy »

А где BIND_TEXTURE?

И, кстати, при последующих перерисовках лучше не glTexImage2D, а glTexSubImage2D использовать - быстрее будет.
А у вас зачем-то эти функции смешаны, текстуру вы какую-то подготавливаете (аж дважды!), но не используете ее.

Например, вот загрузка текстуры из области памяти:

Код: Выделить всё

void gen_texture(IMAGE *image, Window *window, gboolean redraw){
    TEXTURE *texture = window->texture;
    GtkWidget *Area = window->drawingArea;
    GdkGLContext *glContext = gtk_widget_get_gl_context(Area);
    GdkGLDrawable *glDrawable = gtk_widget_get_gl_drawable(Area);
    if (!gdk_gl_drawable_gl_begin(glDrawable, glContext))
        g_assert_not_reached();
    glEnable(GL_TEXTURE_2D);
    if(!texture){
        INIT(window->texture, TEXTURE);
        texture = window->texture;
        if(!texture){
            g_err(_("Can't allocate memory for texture"));
            return;
        }
        glGenTextures(1, &texture->tex);
    }
    glBindTexture(GL_TEXTURE_2D, texture->tex);
    if(image && image->data){
        int i,j, k, w = image->width, h = image->height;
        GLfloat *tex = malloc(w * h * sizeof(GLfloat));
        GLfloat min = image->stat.min, wd = image->stat.max - min;
        GLfloat *ptri = image->data, *ptro = tex;
        #pragma omp parallel for
        for(i=0; i<h; i++){
            k = i*w;
            for(j=0; j<w; j++, k++){
                ptro[k] = (ptri[k] - min) / wd;
            }
        }
        if(redraw)
            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image->width, image->height,
                    GL_LUMINANCE, GL_FLOAT, tex); // s/image->data/tex/
        else
            glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, image->width, image->height,
                    0, GL_LUMINANCE, GL_FLOAT, tex);
        texture->w = image->width; texture->h = image->height;
        free(tex);
    }
    else{
        // Empty texture
        glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, 10., 10.,
                    0, GL_INTENSITY, GL_FLOAT, NULL);
    }
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
    glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
    glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glDisable(GL_TEXTURE_2D);
    gdk_gl_drawable_gl_end(glDrawable);
    g_signal_connect(Area, "expose-event", G_CALLBACK(expose), window);
    g_signal_connect(Area, "configure-event", G_CALLBACK(configure), window);
    force_redraw(Area);
}

А вот кусок из функции, где эта текстура отображается на экране:

Код: Выделить всё

    if(texture){
        w = texture->w / 2.; h = texture->h / 2.;
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(window->move.x, window->move.y, 0.);
        glScalef(window->Zoom, window->Zoom, 1.);
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, texture->tex);
        glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, twhite);
        glDisable(GL_BLEND);
        glBegin(GL_QUADS);
            glTexCoord2f(0.0f, 0.0f); glVertex2f(-w, -h );
            glTexCoord2f(1.0f, 0.0f); glVertex2f( w, -h );
            glTexCoord2f(1.0f, 1.0f); glVertex2f( w,  h );
            glTexCoord2f(0.0f, 1.0f); glVertex2f(-w,  h );
        glEnd();
        glDisable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

Надо разбираться, у меня ещё не сложилась полная картина в какой последовательсти всё необходимо сделать.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: OpenGL: отображение JPEG

Сообщение eddy »

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

Да, если не лень ковыряться в чужом сишном коде (да еще и с GTK), можете глянуть там же на пре-альфа версию FITS-смотрелки (в ней, правда, полным-полно багов, но картинку отображает :) ).
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

Нет, что то не выходит каменный цветок. Итак, что я делаю...
инициализация

Код: Выделить всё

//цвет фона
glClearColor(0.0, 0.0, 0.0, 0.0);
//генерирую имя для текстуры
glGenTextures(1, &texture);
//устанавливаю параметры тектуры
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

изменение размера

Код: Выделить всё

//включаю работу с текстурами
glEnable(GL_TEXTURE_2D);
//никак на поведение не влияет
//glBindTexture(GL_TEXTURE_2D, texture);
//устанавливаю режим
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//конвертирую изображение в понятный OpenGL формат, использую QGLWidget::convertToGLFormat
image = convert_to_GL(jpg);
//генерирую текстуру
if (1 == frame_number)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA, width, height, 0,
                     GL_RGBA, GL_UNSIGNED_BYTE, image.bits());
else
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
                        GL_RGBA, GL_UNSIGNED_BYTE, image.bits());
//прекращение работы с текстурой
glDisable(GL_TEXTURE_2D);
//установка режима просмотра
glPixelZoom(1, 1);
glViewport(0, 0, width, height);

просмотр

Код: Выделить всё

//очищаю буфер
glClear(GL_COLOR_BUFFER_BIT);
//включаю работу с текстурами
glEnable(GL_TEXTURE_2D);
//использую определённую тектуру
glBindTexture(GL_TEXTURE_2D, texture);
//сообщаю, что рисую прямоугольник
glBegin(GL_QUADS);
//установка координат углов, учитываю, что нулевая точка - левый нижний угол
glTexCoord2f(0.0, 1.0);
glVertex3f(0.0, image.height(), 0.0);
glTexCoord2f(0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(image.width(), 0.0, 0.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(image.width(), image.height(), 0.0);
glEnd();
//прекращение работы с текстурой
glDisable(GL_TEXTURE_2D);
//отображения изображения
//glDrawPixels(image.width(), image.height(), GL_RGBA,
    //         GL_UNSIGNED_BYTE, image.bits());

Проблемы:
- при отключении glDrawPixels отображается чёрный квадрат в который вписан белый квадрат в правый верхний угол
- при включении glDrawPixels отображается статичная картинка
Что я пропускаю, не учитываю?

Upd: кажется я нашёл причину чёрного фона - генерация текстуры заканчивается ошибкой
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: OpenGL: отображение JPEG

Сообщение eddy »

Что значит
//никак на поведение не влияет
//glBindTexture(GL_TEXTURE_2D, texture);

?
Очень даже влияет. Вы заполняете несуществующую текстуру, а потом пытаетесь вывести другую, незаполненную текстуру.
IMB писал(а):
20.07.2011 10:53
кажется я нашёл причину чёрного фона - генерация текстуры заканчивается ошибкой

Повставляйте в код fprintf(stderr, "%s\n", gluErrorString(glGetError()))
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

eddy писал(а):
20.07.2011 11:21
Что значит
//никак на поведение не влияет
//glBindTexture(GL_TEXTURE_2D, texture);

?
Очень даже влияет. Вы заполняете несуществующую текстуру, а потом пытаетесь вывести другую, незаполненную текстуру.

В том плане, что результат не менялся :)
eddy писал(а):
20.07.2011 11:21
IMB писал(а):
20.07.2011 10:53
кажется я нашёл причину чёрного фона - генерация текстуры заканчивается ошибкой

Повставляйте в код fprintf(stderr, "%s\n", gluErrorString(glGetError()))

glTexSubImage2D вызывает ошибку invalid value.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: OpenGL: отображение JPEG

Сообщение eddy »

glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA

А у вас точно GL_COMPRESSED_RGBA?

Попробуйте для начала без glTexSubImage2D (т.е. переопределять текстуру каждый раз заново).
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

eddy писал(а):
20.07.2011 11:46
А у вас точно GL_COMPRESSED_RGBA?

Если я не ошибся при прочтении, хотя в COMPRESSED не уверен ;)
QImage QGLWidget::convertToGLFormat ( const QImage & img ) [static]

Converts the image img into the unnamed format expected by OpenGL functions such as glTexImage2D().
The returned image is not usable as a QImage, but QImage::width(), QImage::height() and QImage::bits() may be used with OpenGL.
The GL format used is GL_RGBA.

eddy писал(а):
20.07.2011 11:46
Попробуйте для начала без glTexSubImage2D (т.е. переопределять текстуру каждый раз заново)

Попробовал, ошибок нет, но вижу только чёрный фон с белым квадратом.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: OpenGL: отображение JPEG

Сообщение eddy »

IMB писал(а):
20.07.2011 12:18
вижу только чёрный фон с белым квадратом.

Возможно, проблема как раз в формате (GL_COMPRESSED_RGBA). Хотя, не знаю, как у вас работает convert_to_GL(jpg).
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

Это я исправил, привёл вызов функции к виду glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.bits()), но это ничего не изменило.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: OpenGL: отображение JPEG

Сообщение IMB »

Разобрался с положением белого квадрата, который отображался в верхнем правом квадранте.

Код: Выделить всё

void Image::paintGL()
{
//очистка буфера
glClear(GL_COLOR_BUFFER_BIT);
//устанавливает нулевую точку в центре экрана
glLoadIdentity();
glTranslatef(-image.width()/2, -image.height()/2, 0.0);
................
Спасибо сказали: