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 renderchain_set_vertices(void *data, unsigned pass, unsigned vert_width, unsigned vert_height, uint64_t frame_count) { #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_HLSL) #ifdef _XBOX video_shader_ctx_params_t params; video_shader_ctx_info_t shader_info; #endif #endif unsigned width, height; d3d_video_t *d3d = (d3d_video_t*)data; xdk_renderchain_t *chain = d3d ? (xdk_renderchain_t*)d3d->renderchain_data : NULL; video_driver_get_size(&width, &height); if (!chain) return; if (chain->last_width != vert_width || chain->last_height != vert_height) { unsigned i; Vertex vert[4]; void *verts = NULL; chain->last_width = vert_width; chain->last_height = vert_height; float tex_w = vert_width; float tex_h = vert_height; #ifdef _XBOX360 tex_w /= ((float)chain->tex_w); tex_h /= ((float)chain->tex_h); #endif vert[0].x = -1.0f; vert[1].x = 1.0f; vert[2].x = -1.0f; vert[3].x = 1.0f; vert[0].y = -1.0f; vert[1].y = -1.0f; vert[2].y = 1.0f; vert[3].y = 1.0f; #if defined(_XBOX1) vert[0].z = 1.0f; vert[1].z = 1.0f; vert[2].z = 1.0f; vert[3].z = 1.0f; vert[0].rhw = 0.0f; vert[1].rhw = tex_w; vert[2].rhw = 0.0f; vert[3].rhw = tex_w; vert[0].u = tex_h; vert[1].u = tex_h; vert[2].u = 0.0f; vert[3].u = 0.0f; vert[0].v = 0.0f; vert[1].v = 0.0f; vert[2].v = 0.0f; vert[3].v = 0.0f; #elif defined(_XBOX360) vert[0].u = 0.0f; vert[1].u = tex_w; vert[2].u = 0.0f; vert[3].u = tex_w; vert[0].v = tex_h; vert[1].v = tex_h; vert[2].v = 0.0f; vert[3].v = 0.0f; #endif /* Align texels and vertices. */ for (i = 0; i < 4; i++) { vert[i].x -= 0.5f / ((float)chain->tex_w); vert[i].y += 0.5f / ((float)chain->tex_h); } verts = d3d_vertex_buffer_lock(chain->vertex_buf); memcpy(verts, vert, sizeof(vert)); d3d_vertex_buffer_unlock(chain->vertex_buf); } #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_HLSL) #ifdef _XBOX renderchain_set_mvp(d3d, width, height, d3d->dev_rotation); shader_info.data = d3d; shader_info.idx = pass; shader_info.set_active = true; video_shader_driver_use(shader_info); params.data = d3d; params.width = vert_width; params.height = vert_height; params.tex_width = chain->tex_w; params.tex_height = chain->tex_h; params.out_width = width; params.out_height = height; params.frame_counter = (unsigned int)frame_count; params.info = NULL; params.prev_info = NULL; params.feedback_info = NULL; params.fbo_info = NULL; params.fbo_info_cnt = 0; video_shader_driver_set_parameters(params); #endif #endif }