static void gl_update_input_size(gl_t *gl, unsigned width, unsigned height, unsigned pitch) { // Res change. Need to clear out texture. if ((width != gl->last_width[gl->tex_index] || height != gl->last_height[gl->tex_index]) && gl->empty_buf) { gl->last_width[gl->tex_index] = width; gl->last_height[gl->tex_index] = height; glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(pitch)); glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->tex_w); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, gl->tex_w, gl->tex_h, gl->texture_type, gl->texture_fmt, gl->empty_buf); GLfloat xamt = (GLfloat)width / gl->tex_w; GLfloat yamt = (GLfloat)height / gl->tex_h; set_texture_coords(gl->tex_coords, xamt, yamt); } // We might have used different texture coordinates last frame. Edge case if resolution changes very rapidly. else if (width != gl->last_width[(gl->tex_index - 1) & TEXTURES_MASK] || height != gl->last_height[(gl->tex_index - 1) & TEXTURES_MASK]) { GLfloat xamt = (GLfloat)width / gl->tex_w; GLfloat yamt = (GLfloat)height / gl->tex_h; set_texture_coords(gl->tex_coords, xamt, yamt); } }
void gl_renderchain_render(gl_t *gl, uint64_t frame_count, const struct video_tex_info *tex_info, const struct video_tex_info *feedback_info) { unsigned mip_level; video_shader_ctx_mvp_t mvp; video_shader_ctx_coords_t coords; video_shader_ctx_params_t params; video_shader_ctx_info_t shader_info; unsigned width, height; const struct video_fbo_rect *prev_rect; struct video_tex_info *fbo_info; struct video_tex_info fbo_tex_info[GFX_MAX_SHADERS]; int i; GLfloat xamt, yamt; unsigned fbo_tex_info_cnt = 0; GLfloat fbo_tex_coords[8] = {0.0f}; video_driver_get_size(&width, &height); /* Render the rest of our passes. */ gl->coords.tex_coord = fbo_tex_coords; /* Calculate viewports, texture coordinates etc, * and render all passes from FBOs, to another FBO. */ for (i = 1; i < gl->fbo_pass; i++) { video_shader_ctx_mvp_t mvp; video_shader_ctx_coords_t coords; video_shader_ctx_params_t params; const struct video_fbo_rect *rect = &gl->fbo_rect[i]; prev_rect = &gl->fbo_rect[i - 1]; fbo_info = &fbo_tex_info[i - 1]; xamt = (GLfloat)prev_rect->img_width / prev_rect->width; yamt = (GLfloat)prev_rect->img_height / prev_rect->height; set_texture_coords(fbo_tex_coords, xamt, yamt); fbo_info->tex = gl->fbo_texture[i - 1]; fbo_info->input_size[0] = prev_rect->img_width; fbo_info->input_size[1] = prev_rect->img_height; fbo_info->tex_size[0] = prev_rect->width; fbo_info->tex_size[1] = prev_rect->height; memcpy(fbo_info->coord, fbo_tex_coords, sizeof(fbo_tex_coords)); fbo_tex_info_cnt++; glBindFramebuffer(RARCH_GL_FRAMEBUFFER, gl->fbo[i]); shader_info.data = gl; shader_info.idx = i + 1; shader_info.set_active = true; video_shader_driver_use(&shader_info); glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i - 1]); mip_level = i + 1; if (video_shader_driver_mipmap_input(&mip_level) && gl_check_capability(GL_CAPS_MIPMAP)) glGenerateMipmap(GL_TEXTURE_2D); glClear(GL_COLOR_BUFFER_BIT); /* Render to FBO with certain size. */ gl_set_viewport(gl, rect->img_width, rect->img_height, true, false); params.data = gl; params.width = prev_rect->img_width; params.height = prev_rect->img_height; params.tex_width = prev_rect->width; params.tex_height = prev_rect->height; params.out_width = gl->vp.width; params.out_height = gl->vp.height; params.frame_counter = (unsigned int)frame_count; params.info = tex_info; params.prev_info = gl->prev_info; params.feedback_info = feedback_info; params.fbo_info = fbo_tex_info; params.fbo_info_cnt = fbo_tex_info_cnt; video_shader_driver_set_parameters(¶ms); gl->coords.vertices = 4; coords.handle_data = NULL; coords.data = &gl->coords; video_shader_driver_set_coords(&coords); mvp.data = gl; mvp.matrix = &gl->mvp; video_shader_driver_set_mvp(&mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } #if defined(GL_FRAMEBUFFER_SRGB) && !defined(HAVE_OPENGLES) if (gl->has_srgb_fbo) glDisable(GL_FRAMEBUFFER_SRGB); #endif /* Render our last FBO texture directly to screen. */ prev_rect = &gl->fbo_rect[gl->fbo_pass - 1]; xamt = (GLfloat)prev_rect->img_width / prev_rect->width; yamt = (GLfloat)prev_rect->img_height / prev_rect->height; set_texture_coords(fbo_tex_coords, xamt, yamt); /* Push final FBO to list. */ fbo_info = &fbo_tex_info[gl->fbo_pass - 1]; fbo_info->tex = gl->fbo_texture[gl->fbo_pass - 1]; fbo_info->input_size[0] = prev_rect->img_width; fbo_info->input_size[1] = prev_rect->img_height; fbo_info->tex_size[0] = prev_rect->width; fbo_info->tex_size[1] = prev_rect->height; memcpy(fbo_info->coord, fbo_tex_coords, sizeof(fbo_tex_coords)); fbo_tex_info_cnt++; /* Render our FBO texture to back buffer. */ gl_bind_backbuffer(); shader_info.data = gl; shader_info.idx = gl->fbo_pass + 1; shader_info.set_active = true; video_shader_driver_use(&shader_info); glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[gl->fbo_pass - 1]); mip_level = gl->fbo_pass + 1; if (video_shader_driver_mipmap_input(&mip_level) && gl_check_capability(GL_CAPS_MIPMAP)) glGenerateMipmap(GL_TEXTURE_2D); glClear(GL_COLOR_BUFFER_BIT); gl_set_viewport(gl, width, height, false, true); params.data = gl; params.width = prev_rect->img_width; params.height = prev_rect->img_height; params.tex_width = prev_rect->width; params.tex_height = prev_rect->height; params.out_width = gl->vp.width; params.out_height = gl->vp.height; params.frame_counter = (unsigned int)frame_count; params.info = tex_info; params.prev_info = gl->prev_info; params.feedback_info = feedback_info; params.fbo_info = fbo_tex_info; params.fbo_info_cnt = fbo_tex_info_cnt; video_shader_driver_set_parameters(¶ms); gl->coords.vertex = gl->vertex_ptr; gl->coords.vertices = 4; coords.handle_data = NULL; coords.data = &gl->coords; video_shader_driver_set_coords(&coords); mvp.data = gl; mvp.matrix = &gl->mvp; video_shader_driver_set_mvp(&mvp); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); gl->coords.tex_coord = gl->tex_info.coord; }
static void gl_frame_fbo(gl_t *gl, const struct gl_tex_info *tex_info) { GLfloat fbo_tex_coords[8] = {0.0f}; // Render the rest of our passes. glTexCoordPointer(2, GL_FLOAT, 0, fbo_tex_coords); // It's kinda handy ... :) const struct gl_fbo_rect *prev_rect; const struct gl_fbo_rect *rect; struct gl_tex_info *fbo_info; struct gl_tex_info fbo_tex_info[MAX_SHADERS]; unsigned fbo_tex_info_cnt = 0; // Calculate viewports, texture coordinates etc, and render all passes from FBOs, to another FBO. for (int i = 1; i < gl->fbo_pass; i++) { prev_rect = &gl->fbo_rect[i - 1]; rect = &gl->fbo_rect[i]; fbo_info = &fbo_tex_info[i - 1]; GLfloat xamt = (GLfloat)prev_rect->img_width / prev_rect->width; GLfloat yamt = (GLfloat)prev_rect->img_height / prev_rect->height; set_texture_coords(fbo_tex_coords, xamt, yamt); fbo_info->tex = gl->fbo_texture[i - 1]; fbo_info->input_size[0] = prev_rect->img_width; fbo_info->input_size[1] = prev_rect->img_height; fbo_info->tex_size[0] = prev_rect->width; fbo_info->tex_size[1] = prev_rect->height; memcpy(fbo_info->coord, fbo_tex_coords, sizeof(fbo_tex_coords)); pglBindFramebuffer(GL_FRAMEBUFFER, gl->fbo[i]); gl_shader_use(i + 1); glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i - 1]); glClear(GL_COLOR_BUFFER_BIT); // Render to FBO with certain size. gl_set_viewport(gl, rect->img_width, rect->img_height, true, false); gl_shader_set_params(prev_rect->img_width, prev_rect->img_height, prev_rect->width, prev_rect->height, gl->vp_width, gl->vp_height, gl->frame_count, tex_info, gl->prev_info, fbo_tex_info, fbo_tex_info_cnt); glDrawArrays(GL_QUADS, 0, 4); fbo_tex_info_cnt++; } // Render our last FBO texture directly to screen. prev_rect = &gl->fbo_rect[gl->fbo_pass - 1]; GLfloat xamt = (GLfloat)prev_rect->img_width / prev_rect->width; GLfloat yamt = (GLfloat)prev_rect->img_height / prev_rect->height; set_texture_coords(fbo_tex_coords, xamt, yamt); // Render our FBO texture to back buffer. pglBindFramebuffer(GL_FRAMEBUFFER, 0); gl_shader_use(gl->fbo_pass + 1); glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[gl->fbo_pass - 1]); glClear(GL_COLOR_BUFFER_BIT); gl->render_to_tex = false; gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); gl_shader_set_params(prev_rect->img_width, prev_rect->img_height, prev_rect->width, prev_rect->height, gl->vp_width, gl->vp_height, gl->frame_count, tex_info, gl->prev_info, fbo_tex_info, fbo_tex_info_cnt); glVertexPointer(2, GL_FLOAT, 0, vertex_ptr); glDrawArrays(GL_QUADS, 0, 4); glTexCoordPointer(2, GL_FLOAT, 0, gl->tex_coords); }