GCanvas::GCanvas(int width, int height, uint32_t format, RedWindow *win, RenderType rendertype, PixmapCache& pixmap_cache, PaletteCache& palette_cache, GlzDecoderWindow &glz_decoder_window, SurfacesCache &csurfaces) : Canvas(pixmap_cache, palette_cache, glz_decoder_window, csurfaces) , _pixmap (0) , _textures_lost (false) { _pixmap = new RedPixmapGL(width, height, RedDrawable::format_from_surface(format), true, win, rendertype); if (!(_canvas = gl_canvas_create(width, height, SPICE_SURFACE_FMT_DEPTH(format), &pixmap_cache.base, &palette_cache.base, &csurfaces, &glz_decoder(), &jpeg_decoder(), &zlib_decoder()))) { THROW("create canvas failed"); } }
status_t _init_opengl( display_manager_t* p_dspmgr, const char* vertex_shader_path, const char* fragment_shader_path, size_t video_bits_per_pixel, size_t video_width, size_t video_height, size_t depth_bits_per_pixel, size_t depth_width, size_t depth_height) { size_t index = 0; char uniform_string[256] = {'\0'}; /* Initialize opengl to have two pixel buffers, one for video data from * the kinect, and another for the depth data. Data types / formats here * have to match those used when initializing the kinect. The pixel * buffers offer fast streaming of data from the kinect to the graphics * card */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR); //glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); glDisable(GL_DEPTH_TEST); /* create video pixel streaming buffer */ for (index = 0; index < TEXTURE_CAPACITY; index++) { p_dspmgr->gl_video_buffers[index] = gl_pixel_buffer_create( video_width, video_height, GL_TEXTURE_2D, /* GL_RGBA, GL_RGB, */ GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, video_bits_per_pixel / 8, GL_DYNAMIC_DRAW); if (NULL == p_dspmgr->gl_video_buffers[index]) { LOG_ERROR("failed to create screen"); return -1; } } /* create depth pixel streaming buffer */ for (index = 0; index < TEXTURE_CAPACITY; index++) { p_dspmgr->gl_depth_buffers[index] = gl_pixel_buffer_create( depth_width, depth_height, GL_TEXTURE_2D, /* GL_RGBA, GL_RED, */ GL_ALPHA, GL_ALPHA, GL_UNSIGNED_SHORT, depth_bits_per_pixel / 8, GL_DYNAMIC_DRAW); if (NULL == p_dspmgr->gl_depth_buffers[index]) { LOG_ERROR("failed to create screen"); return ERR_FAILED_CREATE; } } /* create the canvas, which is simply a square in 3D space upon which the * pixel buffers are drawn */ p_dspmgr->canvas = gl_canvas_create(); if (NULL == p_dspmgr->canvas) { LOG_ERROR("failed to create canvas"); return ERR_FAILED_CREATE; } /* load customized shader programs which handle depth cutoff and masking * of video data by depth data */ p_dspmgr->vertex_shader = gl_shader_load_file( GL_VERTEX_SHADER, vertex_shader_path); if (p_dspmgr->vertex_shader == 0) { LOG_ERROR("failed to load vertex shader"); return -1; } p_dspmgr->fragment_shader = gl_shader_load_file( GL_FRAGMENT_SHADER, fragment_shader_path); if (p_dspmgr->fragment_shader == 0) { LOG_ERROR("failed to load fragment shader"); return -1; } p_dspmgr->shader_program = gl_shader_program( p_dspmgr->vertex_shader, p_dspmgr->fragment_shader); if (p_dspmgr->shader_program == 0) { LOG_ERROR("failed to link shader program"); return -1; } /* get handles into shader program fro variables */ p_dspmgr->uniforms.count = glGetUniformLocation(p_dspmgr->shader_program, "count"); p_dspmgr->uniforms.depth_horizontal_pixel_stride = glGetUniformLocation( p_dspmgr->shader_program, "depth_horizontal_pixel_stride"); p_dspmgr->uniforms.depth_vertical_pixel_stride = glGetUniformLocation( p_dspmgr->shader_program, "depth_vertical_pixel_stride"); p_dspmgr->attributes.position = glGetAttribLocation(p_dspmgr->shader_program, "position"); /* check that these uniforms retrieved successfully */ if ((p_dspmgr->uniforms.count < 0) || (p_dspmgr->attributes.position < 0) || (p_dspmgr->uniforms.depth_vertical_pixel_stride < 0) || (p_dspmgr->uniforms.depth_horizontal_pixel_stride < 0)) { LOG_ERROR( "failed to get uniform/attribute locations from shaders"); return ERR_FAILED_CREATE; } /* get array of video textures, depth textures and depth cutoffs */ for (index = 0; index < TEXTURE_CAPACITY; index++) { if (sprintf(uniform_string, "video_texture_%02i", (int)index) < 0) { LOG_ERROR("failed to create string for uniform"); return ERR_FAILED_CREATE; } p_dspmgr->uniforms.video_textures[index] = glGetUniformLocation(p_dspmgr->shader_program, uniform_string); if (sprintf(uniform_string, "depth_texture_%02i", (int)index) < 0) { LOG_ERROR("failed to create string for uniform"); return ERR_FAILED_CREATE; } p_dspmgr->uniforms.depth_textures[index] = glGetUniformLocation(p_dspmgr->shader_program, uniform_string); if (sprintf(uniform_string, "depth_cutoff_%02i", (int)index) < 0) { LOG_ERROR("failed to create string for uniform"); return ERR_FAILED_CREATE; } p_dspmgr->uniforms.depth_cutoffs[index] = glGetUniformLocation(p_dspmgr->shader_program, uniform_string); if ((p_dspmgr->uniforms.video_textures[index] < 0) || (p_dspmgr->uniforms.depth_textures[index] < 0) || (p_dspmgr->uniforms.depth_cutoffs[index] < 0)) { LOG_ERROR("failed to get uniform/attribute locations from shaders"); return ERR_FAILED_CREATE; } } return NO_ERROR; }