void texture_setimage(texture_t tex, const void *data, uint32_t row_bytes, bool flip) { void *ptr; uint32_t row_bytes_out; uint32_t row_copy; int32_t height = (int32_t)texture_getheight(tex); int32_t y; if (!texture_map(tex, &ptr, &row_bytes_out)) return; row_copy = (row_bytes < row_bytes_out) ? row_bytes : row_bytes_out; if (flip) { for (y = height-1; y >= 0; y--) memcpy((uint8_t*)ptr + (uint32_t)y * row_bytes_out, (uint8_t*)data + (uint32_t)y * row_bytes, row_copy); } else if (row_bytes == row_bytes_out) { memcpy(ptr, data, row_copy * height); } else { for (y = 0; y < height; y++) memcpy((uint8_t*)ptr + (uint32_t)y * row_bytes_out, (uint8_t*)data + (uint32_t)y * row_bytes, row_copy); } }
void texture_setimage(texture_t tex, const void *data, uint32_t linesize, bool flip) { if (!thread_graphics || !tex) return; void *ptr; uint32_t linesize_out; uint32_t row_copy; int32_t height = (int32_t)texture_getheight(tex); int32_t y; if (!texture_map(tex, &ptr, &linesize_out)) return; row_copy = (linesize < linesize_out) ? linesize : linesize_out; if (flip) { for (y = height-1; y >= 0; y--) memcpy((uint8_t*)ptr + (uint32_t)y * linesize_out, (uint8_t*)data + (uint32_t)y * linesize, row_copy); } else if (linesize == linesize_out) { memcpy(ptr, data, row_copy * height); } else { for (y = 0; y < height; y++) memcpy((uint8_t*)ptr + (uint32_t)y * linesize_out, (uint8_t*)data + (uint32_t)y * linesize, row_copy); } texture_unmap(tex); }
void gs_draw_sprite(texture_t tex, uint32_t flip, uint32_t width, uint32_t height) { graphics_t graphics = thread_graphics; float fcx, fcy; struct vb_data *data; assert(tex); if (gs_gettexturetype(tex) != GS_TEXTURE_2D) { blog(LOG_ERROR, "A sprite must be a 2D texture"); return; } fcx = width ? (float)width : (float)texture_getwidth(tex); fcy = height ? (float)height : (float)texture_getheight(tex); data = vertexbuffer_getdata(graphics->sprite_buffer); if (texture_isrect(tex)) build_sprite_rect(data, tex, fcx, fcy, flip); else build_sprite_norm(data, fcx, fcy, flip); vertexbuffer_flush(graphics->sprite_buffer, false); gs_load_vertexbuffer(graphics->sprite_buffer); gs_load_indexbuffer(NULL); gs_draw(GS_TRISTRIP, 0, 0); }
static void image_source_update(void *data, obs_data_t settings) { struct image_source *context = data; const char *file = obs_data_getstring(settings, "file"); gs_entercontext(obs_graphics()); if (context->tex) { texture_destroy(context->tex); context->tex = NULL; } if (file) { context->tex = gs_create_texture_from_file(file); if (context->tex) { context->cx = texture_getwidth(context->tex); context->cy = texture_getheight(context->tex); } else { warn("failed to load texture '%s'", file); context->cx = 0; context->cy = 0; } } gs_leavecontext(); }
static inline uint32_t get_target_height(struct gs_device *device) { if (!device->cur_render_target) return device_getheight(device); if (device->cur_render_target->type == GS_TEXTURE_2D) return texture_getheight(device->cur_render_target); else /* cube map */ return cubetexture_getsize(device->cur_render_target); }
static inline void build_sprite_rect(struct vb_data *data, texture_t tex, float fcx, float fcy, uint32_t flip) { float start_u, end_u; float start_v, end_v; float width = (float)texture_getwidth(tex); float height = (float)texture_getheight(tex); assign_sprite_rect(&start_u, &end_u, width, (flip & GS_FLIP_U) != 0); assign_sprite_rect(&start_v, &end_v, height, (flip & GS_FLIP_V) != 0); build_sprite(data, fcx, fcy, start_u, end_u, start_v, end_v, flip); }
static bool set_texture_size(obs_source_t source, struct source_frame *frame) { if (source->output_texture) { uint32_t width = texture_getwidth(source->output_texture); uint32_t height = texture_getheight(source->output_texture); if (width == frame->width && height == frame->height) return true; } texture_destroy(source->output_texture); source->output_texture = gs_create_texture(frame->width, frame->height, GS_RGBA, 1, NULL, GS_DYNAMIC); return source->output_texture != NULL; }
static inline void render_output_texture(struct obs_core_video *video, int cur_texture, int prev_texture) { texture_t texture = video->render_textures[prev_texture]; texture_t target = video->output_textures[cur_texture]; uint32_t width = texture_getwidth(target); uint32_t height = texture_getheight(target); /* TODO: replace with actual downscalers or unpackers */ effect_t effect = video->default_effect; technique_t tech = effect_gettechnique(effect, "DrawMatrix"); eparam_t image = effect_getparambyname(effect, "image"); eparam_t matrix = effect_getparambyname(effect, "color_matrix"); size_t passes, i; if (!video->textures_rendered[prev_texture]) return; gs_setrendertarget(target, NULL); set_render_size(width, height); /* TODO: replace with programmable code */ const float mat_val[16] = { -0.100644f, -0.338572f, 0.439216f, 0.501961f, 0.182586f, 0.614231f, 0.062007f, 0.062745f, 0.439216f, -0.398942f, -0.040274f, 0.501961f, 0.000000f, 0.000000f, 0.000000f, 1.000000f }; effect_setval(effect, matrix, mat_val, sizeof(mat_val)); effect_settexture(effect, image, texture); passes = technique_begin(tech); for (i = 0; i < passes; i++) { technique_beginpass(tech, i); gs_draw_sprite(texture, 0, width, height); technique_endpass(tech); } technique_end(tech); video->textures_output[cur_texture] = true; }
static uint32_t random_getheight(void *data) { struct random_tex *rt = data; return texture_getheight(rt->texture); }