static bool load_textures(void) { unsigned i; if (!cg_shader->luts) return true; glGenTextures(cg_shader->luts, lut_textures); for (i = 0; i < cg_shader->luts; i++) { RARCH_LOG("Loading image from: \"%s\".\n", cg_shader->lut[i].path); struct texture_image img = {0}; if (!texture_image_load(cg_shader->lut[i].path, &img)) { RARCH_ERR("Failed to load picture ...\n"); return false; } load_texture_data(lut_textures[i], &img, cg_shader->lut[i].filter != RARCH_FILTER_NEAREST, gl_wrap_type_to_enum(cg_shader->lut[i].wrap)); texture_image_free(&img); } glBindTexture(GL_TEXTURE_2D, 0); return true; }
bool gl_load_luts(const struct gfx_shader *generic_shader, GLuint *lut_textures) { unsigned i, num_luts; num_luts = min(generic_shader->luts, GFX_MAX_TEXTURES); if (!generic_shader->luts) return true; // Original shader_glsl.c code only generated one texture handle. I assume // it was a bug, but if not, replace num_luts with 1 when GLSL is used. glGenTextures(num_luts, lut_textures); for (i = 0; i < num_luts; i++) { struct texture_image img = {0}; RARCH_LOG("Loading texture image from: \"%s\" ...\n", generic_shader->lut[i].path); if (!texture_image_load(&img, generic_shader->lut[i].path)) { RARCH_ERR("Failed to load texture image from: \"%s\"\n", generic_shader->lut[i].path); return false; } gl_load_texture_data(lut_textures[i], &img, gl_wrap_type_to_enum(generic_shader->lut[i].wrap), generic_shader->lut[i].filter != RARCH_FILTER_NEAREST, generic_shader->lut[i].mipmap); texture_image_free(&img); } glBindTexture(GL_TEXTURE_2D, 0); return true; }
void gl_load_texture_data(GLuint id, enum gfx_wrap_type wrap_type, enum texture_filter_type filter_type, unsigned alignment, unsigned width, unsigned height, const void *frame, unsigned base_size) { GLint mag_filter, min_filter; GLenum wrap; bool want_mipmap = false; bool rgb32 = (base_size == (sizeof(uint32_t))); glBindTexture(GL_TEXTURE_2D, id); wrap = gl_wrap_type_to_enum(wrap_type); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); switch (filter_type) { case TEXTURE_FILTER_MIPMAP_LINEAR: min_filter = GL_LINEAR_MIPMAP_NEAREST; mag_filter = GL_LINEAR; #ifndef HAVE_PSGL want_mipmap = true; #endif break; case TEXTURE_FILTER_MIPMAP_NEAREST: min_filter = GL_NEAREST_MIPMAP_NEAREST; mag_filter = GL_NEAREST; #ifndef HAVE_PSGL want_mipmap = true; #endif break; case TEXTURE_FILTER_NEAREST: min_filter = GL_NEAREST; mag_filter = GL_NEAREST; break; case TEXTURE_FILTER_LINEAR: default: min_filter = GL_LINEAR; mag_filter = GL_LINEAR; break; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); #ifndef HAVE_PSGL glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); #endif glTexImage2D(GL_TEXTURE_2D, 0, (driver.gfx_use_rgba || !rgb32) ? GL_RGBA : RARCH_GL_INTERNAL_FORMAT32, width, height, 0, (driver.gfx_use_rgba || !rgb32) ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, (rgb32) ? RARCH_GL_FORMAT32 : GL_UNSIGNED_SHORT_4_4_4_4, frame); if (want_mipmap) glGenerateMipmap(GL_TEXTURE_2D); }
static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture) { unsigned mip_level; bool fp_fbo; GLenum min_filter, mag_filter, wrap_enum; video_shader_ctx_filter_t filter_type; video_shader_ctx_wrap_t wrap = {0}; bool mipmapped = false; bool smooth = false; settings_t *settings = config_get_ptr(); GLuint base_filt = settings->video.smooth ? GL_LINEAR : GL_NEAREST; GLuint base_mip_filt = settings->video.smooth ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST; glBindTexture(GL_TEXTURE_2D, texture); mip_level = i + 2; mipmapped = video_shader_driver_mipmap_input(&mip_level); min_filter = mipmapped ? base_mip_filt : base_filt; filter_type.index = i + 2; filter_type.smooth = &smooth; if (video_shader_driver_filter_type(&filter_type)) { min_filter = mipmapped ? (smooth ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST) : (smooth ? GL_LINEAR : GL_NEAREST); } mag_filter = min_filter_to_mag(min_filter); wrap.idx = i + 2; video_shader_driver_wrap_type(&wrap); wrap_enum = gl_wrap_type_to_enum(wrap.type); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_enum); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_enum); fp_fbo = gl->fbo_scale[i].fp_fbo; if (fp_fbo) { if (!gl->has_fp_fbo) RARCH_ERR("[GL]: Floating-point FBO was requested, but is not supported. Falling back to UNORM. Result may band/clip/etc.!\n"); } #ifndef HAVE_OPENGLES2 if (fp_fbo && gl->has_fp_fbo) { RARCH_LOG("[GL]: FBO pass #%d is floating-point.\n", i); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, gl->fbo_rect[i].width, gl->fbo_rect[i].height, 0, GL_RGBA, GL_FLOAT, NULL); } else #endif { #ifndef HAVE_OPENGLES bool srgb_fbo = gl->fbo_scale[i].srgb_fbo; if (!fp_fbo && srgb_fbo) { if (!gl->has_srgb_fbo) RARCH_ERR("[GL]: sRGB FBO was requested, but it is not supported. Falling back to UNORM. Result may have banding!\n"); } if (settings->video.force_srgb_disable) srgb_fbo = false; if (srgb_fbo && gl->has_srgb_fbo) { RARCH_LOG("[GL]: FBO pass #%d is sRGB.\n", i); #ifdef HAVE_OPENGLES2 /* EXT defines are same as core GLES3 defines, * but GLES3 variant requires different arguments. */ glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, gl->fbo_rect[i].width, gl->fbo_rect[i].height, 0, gl->has_srgb_fbo_gles3 ? GL_RGBA : GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, NULL); #else glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, gl->fbo_rect[i].width, gl->fbo_rect[i].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); #endif } else #endif { #ifdef HAVE_OPENGLES2 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, gl->fbo_rect[i].width, gl->fbo_rect[i].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); #else /* Avoid potential performance * reductions on particular platforms. */ glTexImage2D(GL_TEXTURE_2D, 0, RARCH_GL_INTERNAL_FORMAT32, gl->fbo_rect[i].width, gl->fbo_rect[i].height, 0, RARCH_GL_TEXTURE_TYPE32, RARCH_GL_FORMAT32, NULL); #endif } } }