PDA

View Full Version : View JPEG



Debian
07-26-2011, 01:30 AM
Hello!
I try view JPEG from IP-camera, I have used Qt 4.7.
My code:
initializeGL()

glClearColor(0.0, 0.0, 0.0, 0.0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_CUBE_MAP);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
resizeGL(int width, int height)

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
//convert QByteArray
image = QGLWidget::convertToGLFormat(QImage::fromData(jpg) );
if (1 == frame_number)
glTexImage2D(GL_TEXTURE_2D, 0, 4, image.width(), image.height(),
0, GL_RGBA, GL_UNSIGNED_BYTE, image.bits());
else
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image.width(),
image.height(), GL_RGBA, GL_UNSIGNED_BYTE, image.bits());
glDisable(GL_TEXTURE_2D);
glPixelZoom(1.0, 1.0);
paintGL()

glClear(GL_COLOR_BUFFER_BIT);
glTranslatef(-image.width()/2, -image.height()/2, 0.0);
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());
I run resizeGL and paintGL after each frame.
I successfully get JPEG, but I have two problems:
- if I comment glDrawPixels I view only white rectangle
- if I use glDrawPixels I view static image
How can I solve this problem?
Thank you and excuse me for my bad english.

_arts_
07-26-2011, 02:39 AM
Simply by updating your image every frame (or almost if you want to achieve a constant framerate from your camera).

The easiest and a fast solution is to use glCopyTexSubImage. I think you can achieve this with glDrawPixels but it will be slower.

Debian
07-26-2011, 02:56 AM
Hello and thank you for your reply!
Where I need use glCopyTexSubImage? I try use it in resize and paint, but I don't get any changes.

Also I view strange:

GLFormat glformat;
qDebug() << "OpenGL version" << glformat.majorVersion()
<< glformat.minorVersion()
<< glformat.openGLVersionFlags()
<< "\npbuffer" << QGLPixelBuffer::hasOpenGLPbuffers();
I get this OpenGL version 1 0 QFlags(0x1|0x2|0x4|0x8|0x10|0x20|0x40)
pbuffer true
But glxinfo have another info:

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
OpenGL extensions:
GL_ARB_depth_texture, GL_ARB_fragment_program,
GL_ARB_fragment_program_shadow, GL_ARB_fragment_shader,
GL_ARB_half_float_pixel, GL_ARB_imaging, GL_ARB_multisample,
GL_ARB_multitexture, GL_ARB_occlusion_query, GL_ARB_pixel_buffer_object,
GL_ARB_point_parameters, GL_ARB_point_sprite, GL_ARB_shadow,
GL_ARB_shader_objects, GL_ARB_shading_language_100,
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_dot3,
GL_ARB_texture_mirrored_repeat, GL_ARB_texture_rectangle,
GL_ARB_transpose_matrix, GL_ARB_vertex_buffer_object,
GL_ARB_vertex_program, GL_ARB_vertex_shader, GL_ARB_window_pos,
GL_S3_s3tc, GL_EXT_texture_env_add, GL_EXT_abgr, GL_EXT_bgra,
GL_EXT_blend_color, GL_EXT_blend_func_separate, GL_EXT_blend_minmax,
GL_EXT_blend_subtract, GL_EXT_compiled_vertex_array, GL_EXT_Cg_shader,
GL_EXT_draw_range_elements, GL_EXT_fog_coord, GL_EXT_framebuffer_blit,
GL_EXT_framebuffer_multisample, GL_EXT_framebuffer_object,
GL_EXT_gpu_program_parameters, GL_EXT_multi_draw_arrays,
GL_EXT_packed_depth_stencil, GL_EXT_packed_pixels,
GL_EXT_paletted_texture, GL_EXT_pixel_buffer_object,
GL_EXT_point_parameters, 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_two_side,
GL_EXT_stencil_wrap, GL_EXT_texture3D, GL_EXT_texture_compression_s3tc,
GL_EXT_texture_cube_map, GL_EXT_texture_edge_clamp,
GL_EXT_texture_env_combine, GL_EXT_texture_env_dot3,
GL_EXT_texture_filter_anisotropic, GL_EXT_texture_lod,
GL_EXT_texture_lod_bias, GL_EXT_texture_object, GL_EXT_texture_sRGB,
GL_EXT_timer_query, GL_EXT_vertex_array, GL_IBM_rasterpos_clip,
GL_IBM_texture_mirrored_repeat, GL_KTX_buffer_region, GL_NV_blend_square,
GL_NV_copy_depth_to_color, GL_NV_depth_clamp, GL_NV_fence,
GL_NV_float_buffer, GL_NV_fog_distance, GL_NV_fragment_program,
GL_NV_fragment_program_option, GL_NV_framebuffer_multisample_coverage,
GL_NV_half_float, GL_NV_light_max_exponent, GL_NV_multisample_filter_hint,
GL_NV_occlusion_query, GL_NV_packed_depth_stencil, GL_NV_pixel_data_range,
GL_NV_point_sprite, GL_NV_primitive_restart, GL_NV_register_combiners,
GL_NV_register_combiners2, GL_NV_texgen_reflection,
GL_NV_texture_compression_vtc, GL_NV_texture_env_combine4,
GL_NV_texture_expand_normal, GL_NV_texture_rectangle,
GL_NV_texture_shader, GL_NV_texture_shader2, GL_NV_texture_shader3,
GL_NV_vertex_array_range, GL_NV_vertex_array_range2, GL_NV_vertex_program,
GL_NV_vertex_program1_1, GL_NV_vertex_program2,
GL_NV_vertex_program2_option, GL_SGIS_generate_mipmap,
GL_SGIS_texture_lod, GL_SGIX_depth_texture, GL_SGIX_shadow,
GL_SUN_slice_accum
Why Qt return 1.0 as version OpenGL?

_arts_
07-26-2011, 03:55 AM
I reread your first post.
Can you ensure paintGL is not called only once ? I mean if you try to do a little animation in this function, do you see any animation or do you have a static image ? If you have a static image, try to see how QT works to make animations work (basically paintGL should be called in a callback function).

glCopyTexSubImage should be called wherever you need to update the content of your texture data.

Try this: "glGetString(GL_VERSION)" and tell what result do you have.

Debian
07-26-2011, 04:10 AM
Can you ensure paintGL is not called only once ?
Yes, I insert in paintGL debug output qDebug("paintGL: texture id %d", texture);
I see next output while I don't close programm:

paintGL: texture id 1
paintGL: texture id 1
paintGL: texture id 1
.........


Try this: "glGetString(GL_VERSION)" and tell what result do you have.
I insert in constructor next code:

QGLFormat glformat;
glformat.setVersion(1, 4);
qDebug() << "OpenGL version" << glformat.majorVersion()
<< glformat.minorVersion()
<< glformat.openGLVersionFlags()
<< "\npbuffer" << QGLPixelBuffer::hasOpenGLPbuffers();
makeCurrent();
qDebug() << "OpenGL version" << (char *)glGetString(GL_VERSION);
And get this output:

OpenGL version 1 4 QFlags(0x1|0x2|0x4|0x8|0x10|0x20|0x40)
pbuffer true
OpenGL version 2.1.2 NVIDIA 173.14.27

_arts_
07-26-2011, 04:25 AM
Why do you "set" the version with glformat.setVersion(1, 4) ? I think you can forget it.

Where do you update your "image.bits()" ? From me, image.bits always have the same content.

Debian
07-26-2011, 04:40 AM
Why do you "set" the version with glformat.setVersion(1, 4) ? I think you can forget it.
Ok, I don't use setVersion and get this output:

OpenGL version 1 0 QFlags(0x1|0x2|0x4|0x8|0x10|0x20|0x40)
pbuffer true
OpenGL version 2.1.2 NVIDIA 173.14.27


Where do you update your "image.bits()" ? From me, image.bits always have the same content.
This is very simple:

QByteArray jpg; //array for image
quint32 frame_size; //image size
quint16 frame_part; //number packets for send frame

jpg.truncate(0);
jpg.reserve(frame_size + 1);

void Image::fill_data(const quint16 num, const quint16 size,
const char *data)
{
jpg.append(data, size);

cur_size += size;
cur_packet = num;

if (cur_size == frame_size &amp;&amp; cur_packet == frame_part)
emit view_image();
}

void Image::view_image()
{
resizeGL(frame_resolution.width(), frame_resolution.height());
paintGL();
}
When I get frame, check frame size, I run view_image.
In resizeGL I convert jpg to OpenGL format and use it data in glTexImage2D.
After paintGL I get new frame.

_arts_
07-26-2011, 05:08 AM
OK. I know very very few about QT. But:


jpg.append(data, size);
Since jpg is a file variable, won't this call append, and append... the data to jpg (so the first n bytes will always be the same, and could result in memory swap) ? Wouldn't it better to replace the data ?

Can you try to do this ?



void Image::fill_data(const quint16 num, const quint16 size,
const char *data)
{
glBindTexture (GL_TEXTURE_2D, texture_id);
glTexSubImage2D (GL_TEXTURE_2D, 0, 0,0, image_width, image_height, GL_RGB, GL_UNSIGNED_BYTE, data);
}


with texture_id the texture_id returned when creating the texture, and image_width and image_height the image size.
And of course, avoid TexSubImage in your rendering function.

Debian
07-26-2011, 05:18 AM
Since jpg is a file variable, won't this call append, and append... the data to jpg (so the first n bytes will always be the same, and could result in memory swap) ? Wouldn't it better to replace the data ?

No, jpg isn't file, it is buffer, I get it via network and network packets have maximum size 1400 byte.

That will change if I generate texture in fill_data?

Debian
07-26-2011, 07:01 AM
Can you try to do this ?



void Image::fill_data(const quint16 num, const quint16 size,
const char *data)
{
glBindTexture (GL_TEXTURE_2D, texture_id);
glTexSubImage2D (GL_TEXTURE_2D, 0, 0,0, image_width, image_height, GL_RGB, GL_UNSIGNED_BYTE, data);
}


I try, but this is not solve problem.

_arts_
07-27-2011, 01:50 AM
Sincerly, I don't know. Updating your image data with glTexImage2D or glTexSubImage2D is enough to make the image change each frame, and so see an animated texture.
Ensure the format of your data are the same than GL expects them. Ensure you bind to the same texture id.

Debian
07-29-2011, 12:10 AM
Hello again!
Information about my videocard:

$ 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
OpenGL extensions:
GL_ARB_depth_texture, GL_ARB_fragment_program,
GL_ARB_fragment_program_shadow, GL_ARB_fragment_shader,
GL_ARB_half_float_pixel, GL_ARB_imaging, GL_ARB_multisample,
GL_ARB_multitexture, GL_ARB_occlusion_query, GL_ARB_pixel_buffer_object,
GL_ARB_point_parameters, GL_ARB_point_sprite, GL_ARB_shadow,
GL_ARB_shader_objects, GL_ARB_shading_language_100,
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_dot3,
GL_ARB_texture_mirrored_repeat, GL_ARB_texture_rectangle,
GL_ARB_transpose_matrix, GL_ARB_vertex_buffer_object,
GL_ARB_vertex_program, GL_ARB_vertex_shader, GL_ARB_window_pos,
GL_S3_s3tc, GL_EXT_texture_env_add, GL_EXT_abgr, GL_EXT_bgra,
GL_EXT_blend_color, GL_EXT_blend_func_separate, GL_EXT_blend_minmax,
GL_EXT_blend_subtract, GL_EXT_compiled_vertex_array, GL_EXT_Cg_shader,
GL_EXT_draw_range_elements, GL_EXT_fog_coord, GL_EXT_framebuffer_blit,
GL_EXT_framebuffer_multisample, GL_EXT_framebuffer_object,
GL_EXT_gpu_program_parameters, GL_EXT_multi_draw_arrays,
GL_EXT_packed_depth_stencil, GL_EXT_packed_pixels,
GL_EXT_paletted_texture, GL_EXT_pixel_buffer_object,
GL_EXT_point_parameters, 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_two_side,
GL_EXT_stencil_wrap, GL_EXT_texture3D, GL_EXT_texture_compression_s3tc,
GL_EXT_texture_cube_map, GL_EXT_texture_edge_clamp,
GL_EXT_texture_env_combine, GL_EXT_texture_env_dot3,
GL_EXT_texture_filter_anisotropic, GL_EXT_texture_lod,
GL_EXT_texture_lod_bias, GL_EXT_texture_object, GL_EXT_texture_sRGB,
GL_EXT_timer_query, GL_EXT_vertex_array, GL_IBM_rasterpos_clip,
GL_IBM_texture_mirrored_repeat, GL_KTX_buffer_region, GL_NV_blend_square,
GL_NV_copy_depth_to_color, GL_NV_depth_clamp, GL_NV_fence,
GL_NV_float_buffer, GL_NV_fog_distance, GL_NV_fragment_program,
GL_NV_fragment_program_option, GL_NV_framebuffer_multisample_coverage,
GL_NV_half_float, GL_NV_light_max_exponent, GL_NV_multisample_filter_hint,
GL_NV_occlusion_query, GL_NV_packed_depth_stencil, GL_NV_pixel_data_range,
GL_NV_point_sprite, GL_NV_primitive_restart, GL_NV_register_combiners,
GL_NV_register_combiners2, GL_NV_texgen_reflection,
GL_NV_texture_compression_vtc, GL_NV_texture_env_combine4,
GL_NV_texture_expand_normal, GL_NV_texture_rectangle,
GL_NV_texture_shader, GL_NV_texture_shader2, GL_NV_texture_shader3,
GL_NV_vertex_array_range, GL_NV_vertex_array_range2, GL_NV_vertex_program,
GL_NV_vertex_program1_1, GL_NV_vertex_program2,
GL_NV_vertex_program2_option, GL_SGIS_generate_mipmap,
GL_SGIS_texture_lod, GL_SGIX_depth_texture, GL_SGIX_shadow,
GL_SUN_slice_accum
And I get information what my card don't support NPOT textures, but I can use GL_ARB_texture_rectangle extension.
I read http://www.opengl.org/registry/specs/ARB/texture_rectangle.txt and try it, but I get error invalid operation in glEnable(GL_TEXTURE_RECTANGLE_ARB) and glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, ...) operations.

QString Image::glerror_to_text(GLenum err)
{
return QString("GLError [%1] %2").
arg(err, 0, 10).
arg((char *)gluErrorString(err));
}
I get this output:

initializeGL: after glEnable "GLError [1282] invalid operation"
resizeGL: after glTex*Image2D "GLError [1282] invalid operation"
How can I solve this problem?
Thank you.

P.S. When I read http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml and http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml I don't see GL_TEXTURE_RECTANGLE_ARB target, why?

V-man
07-29-2011, 09:30 AM
Because GL_TEXTURE_RECTANGLE_ARB is an extension. You need to read the extension pages

http://www.opengl.org/registry/

http://www.opengl.org/registry/specs/ARB/texture_rectangle.txt

_arts_
07-29-2011, 09:53 AM
V-man, he said he read the specs. And AFAIK, GL_TEXTURE_RECTANGLE_ARB need no function loading process.

I think Qt has something to do with this. Try to set a higher QT GL version (2.0 or so). If it still does not work, I think you should check about a QT GL forum.

V-man
07-30-2011, 04:00 AM
His question was

P.S. When I read http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml and http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml I don't see GL_TEXTURE_RECTANGLE_ARB target, why?

and that's why I answered.

People don't understand the difference between OpenGL and a OpenGL extension. The http://www.opengl.org/sdk/docs don't cover extensions.

Debian
08-01-2011, 02:47 AM
People don't understand the difference between OpenGL and a OpenGL extension. The http://www.opengl.org/sdk/docs don't cover extensions.
Ok, I is only start use OpenGL and don't understand all yet.
But my main question - why I can't see JPEG, where I have error?

_arts_
08-01-2011, 03:21 AM
This pseudo-code should do the work:



// init
GLuint tex_id;
glGenTextures(1, &amp;tex_id);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex_id);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, image_width, image_height, 0, GL_RED, GL_UNSIGNED_BYTE, data);

// draw loop
data = get_data_compatible_with_gl_from_camera();
glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex_id);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0,0, image_width, image_height, GL_RGB, GL_UNSIGNED_BYTE, data);
glBegin (GL_QUADS);
glTexCoord2f (0,0);
glVertex2f (0,0);
glTexCoord2f (image_width, 0);
glVertex2f (quad_width, 0);
glTexCoord2f (image_width, image_height);
glVertex2f (quad_width, quad_height);
glTexCoord2f (0, image_height);
glVertex2f (0, quad_height);
glEnd();
glDisable (GL_TEXTURE_RECTANGLE_ARB);


If you can't get GL_TEXTURE_RECTANGLE_ARB to be recognized, you have several solutions: the best, check a QT forum to know how to do it. The easiest: use squared POT textures.

I really think your issue is a QT issue since you can have different GL versions if you check it directly by GL or threw a Qt function. Unfortunately I never did OpenGL with Qt, so I can't help you more.

And when you'll find why, it will be nice to let us know :)