static void update_yuvconv(void) { int xs, ys, depth; float bri = eq_bri / 100.0; float cont = (eq_cont + 100) / 100.0; float hue = eq_hue / 100.0 * 3.1415927; float sat = (eq_sat + 100) / 100.0; float rgamma = exp(log(8.0) * eq_rgamma / 100.0); float ggamma = exp(log(8.0) * eq_ggamma / 100.0); float bgamma = exp(log(8.0) * eq_bgamma / 100.0); gl_conversion_params_t params = {gl_target, yuvconvtype, {colorspace, levelconv, bri, cont, hue, sat, rgamma, ggamma, bgamma, 0}, texture_width, texture_height, 0, 0, filter_strength, noise_strength}; mp_get_chroma_shift(image_format, &xs, &ys, &depth); params.chrom_texw = params.texw >> xs; params.chrom_texh = params.texh >> ys; params.csp_params.input_shift = -depth & 7; glSetupYUVConversion(¶ms); if (custom_prog) { FILE *f = fopen(custom_prog, "rb"); if (!f) { mp_msg(MSGT_VO, MSGL_WARN, "[gl] Could not read customprog %s\n", custom_prog); } else { char *prog = calloc(1, MAX_CUSTOM_PROG_SIZE + 1); fread(prog, 1, MAX_CUSTOM_PROG_SIZE, f); fclose(f); loadGPUProgram(GL_FRAGMENT_PROGRAM, prog); free(prog); } mpglProgramEnvParameter4f(GL_FRAGMENT_PROGRAM, 0, 1.0 / texture_width, 1.0 / texture_height, texture_width, texture_height); } if (custom_tex) { FILE *f = fopen(custom_tex, "rb"); if (!f) { mp_msg(MSGT_VO, MSGL_WARN, "[gl] Could not read customtex %s\n", custom_tex); } else { int width, height, maxval; mpglActiveTexture(GL_TEXTURE3); if (glCreatePPMTex(custom_trect?GL_TEXTURE_RECTANGLE:GL_TEXTURE_2D, 0, custom_tlin?GL_LINEAR:GL_NEAREST, f, &width, &height, &maxval)) { mpglProgramEnvParameter4f(GL_FRAGMENT_PROGRAM, 1, 1.0 / width, 1.0 / height, width, height); } else mp_msg(MSGT_VO, MSGL_WARN, "[gl] Error parsing customtex %s\n", custom_tex); fclose(f); mpglActiveTexture(GL_TEXTURE0); } } }
static void drawTextureDisplay (void) { struct TexSquare *square = texgrid; int x, y; glColor4f(1.0,1.0,1.0,1.0); if (is_yuv) glEnableYUVConversion(GL_TEXTURE_2D, use_yuv); for (y = 0; y < texnumy; y++) { int thish = texture_height; if (y == texnumy - 1 && image_height % texture_height) thish = image_height % texture_height; for (x = 0; x < texnumx; x++) { int thisw = texture_width; if (x == texnumx - 1 && image_width % texture_width) thisw = image_width % texture_width; glBindTexture (GL_TEXTURE_2D, square->texobj); if (is_yuv) { mpglActiveTexture(GL_TEXTURE1); glBindTexture (GL_TEXTURE_2D, square->uvtexobjs[0]); mpglActiveTexture(GL_TEXTURE2); glBindTexture (GL_TEXTURE_2D, square->uvtexobjs[1]); mpglActiveTexture(GL_TEXTURE0); } if (texdirty) { glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type, square->texture, image_width * image_bytes, 0, 0, thisw, thish, 0); } glDrawTex(square->fx, square->fy, square->fw, square->fh, 0, 0, texture_width, texture_height, texture_width, texture_height, 0, is_yuv, 0, 0); square++; } /* for all texnumx */ } /* for all texnumy */ if (is_yuv) glDisableYUVConversion(GL_TEXTURE_2D, use_yuv); texdirty = 0; }
static int initTextures(void) { struct TexSquare *tsq=0; GLfloat texpercx, texpercy; int s; int x=0, y=0; // textures smaller than 64x64 might not be supported s=64; while (s<image_width) s*=2; texture_width=s; s=64; while (s<image_height) s*=2; texture_height=s; if (!is_yuv) gl_internal_format = getInternalFormat(); /* Test the max texture size */ do { GLint w; glTexImage2D (GL_PROXY_TEXTURE_2D, 0, gl_internal_format, texture_width, texture_height, 0, gl_bitmap_format, gl_bitmap_type, NULL); glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); if (w >= texture_width) break; mp_msg (MSGT_VO, MSGL_V, "[gl_tiled] Needed texture [%dx%d] too big, trying ", texture_width, texture_height); if (texture_width > texture_height) texture_width /= 2; else texture_height /= 2; mp_msg (MSGT_VO, MSGL_V, "[%dx%d] !\n", texture_width, texture_height); if(texture_width < 64 || texture_height < 64) { mp_msg (MSGT_VO, MSGL_FATAL, "[gl_tiled] Give up .. usable texture size not available, or texture config error !\n"); return -1; } } while (texture_width > 1 && texture_height > 1); #ifdef TEXTURE_WIDTH texture_width = TEXTURE_WIDTH; #endif #ifdef TEXTURE_HEIGHT texture_height = TEXTURE_HEIGHT; #endif texnumx = image_width / texture_width; if ((image_width % texture_width) > 0) texnumx++; texnumy = image_height / texture_height; if ((image_height % texture_height) > 0) texnumy++; mp_msg(MSGT_VO, MSGL_V, "[gl_tiled] Creating %dx%d textures of size %dx%d ...\n", texnumx, texnumy, texture_width,texture_height); /* Allocate the texture memory */ texpercx = (GLfloat) texture_width / (GLfloat) image_width; texpercy = (GLfloat) texture_height / (GLfloat) image_height; free(texgrid); texgrid = calloc (texnumx * texnumy, sizeof (struct TexSquare)); raw_line_len = image_width * image_bytes; mp_msg (MSGT_VO, MSGL_DBG2, "[gl_tiled] texture-usage %d*width=%d, %d*height=%d\n", (int) texnumx, (int) texture_width, (int) texnumy, (int) texture_height); tsq = texgrid; for (y = 0; y < texnumy; y++) { for (x = 0; x < texnumx; x++) { tsq->fx = x * texpercx; tsq->fy = y * texpercy; tsq->fw = texpercx; tsq->fh = texpercy; tsq->texobj=0; tsq->uvtexobjs[0] = tsq->uvtexobjs[1] = 0; glGenTextures (1, &(tsq->texobj)); glBindTexture (GL_TEXTURE_2D, tsq->texobj); if (is_yuv) { glGenTextures(2, tsq->uvtexobjs); mpglActiveTexture(GL_TEXTURE1); glBindTexture (GL_TEXTURE_2D, tsq->uvtexobjs[0]); mpglActiveTexture(GL_TEXTURE2); glBindTexture (GL_TEXTURE_2D, tsq->uvtexobjs[1]); mpglActiveTexture(GL_TEXTURE0); } glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR, texture_width, texture_height, 0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (is_yuv) { int xs, ys, depth; int chroma_clear_val = 128; mp_get_chroma_shift(image_format, &xs, &ys, &depth); chroma_clear_val >>= -depth & 7; mpglActiveTexture(GL_TEXTURE1); glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR, texture_width >> xs, texture_height >> ys, chroma_clear_val); mpglActiveTexture(GL_TEXTURE2); glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR, texture_width >> xs, texture_height >> ys, chroma_clear_val); mpglActiveTexture(GL_TEXTURE0); } tsq++; } /* for all texnumx */ } /* for all texnumy */ return 0; }
/** * \brief Initialize a (new or reused) OpenGL context. * set global gl-related variables to their default values */ static int initGl(uint32_t d_width, uint32_t d_height) { GLint scale_type = get_scale_type(0); autodetectGlExtensions(); gl_target = use_rectangle == 1 ? GL_TEXTURE_RECTANGLE : GL_TEXTURE_2D; yuvconvtype = SET_YUV_CONVERSION(use_yuv) | SET_YUV_LUM_SCALER(lscale) | SET_YUV_CHROM_SCALER(cscale); texSize(image_width, image_height, &texture_width, &texture_height); mpglDisable(GL_BLEND); mpglDisable(GL_DEPTH_TEST); mpglDepthMask(GL_FALSE); mpglDisable(GL_CULL_FACE); mpglEnable(gl_target); mpglDrawBuffer(vo_doublebuffering?GL_BACK:GL_FRONT); mpglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n", texture_width, texture_height); glCreateClearTex(gl_target, gl_texfmt, gl_format, gl_type, scale_type, texture_width, texture_height, 0); if (mipmap_gen) mpglTexParameteri(gl_target, GL_GENERATE_MIPMAP, GL_TRUE); if (is_yuv) { int i; int xs, ys; scale_type = get_scale_type(1); mp_get_chroma_shift(image_format, &xs, &ys); mpglGenTextures(21, default_texs); default_texs[21] = 0; for (i = 0; i < 7; i++) { mpglActiveTexture(GL_TEXTURE1 + i); mpglBindTexture(GL_TEXTURE_2D, default_texs[i]); mpglBindTexture(GL_TEXTURE_RECTANGLE, default_texs[i + 7]); mpglBindTexture(GL_TEXTURE_3D, default_texs[i + 14]); } mpglActiveTexture(GL_TEXTURE1); glCreateClearTex(gl_target, gl_texfmt, gl_format, gl_type, scale_type, texture_width >> xs, texture_height >> ys, 128); if (mipmap_gen) mpglTexParameteri(gl_target, GL_GENERATE_MIPMAP, GL_TRUE); mpglActiveTexture(GL_TEXTURE2); glCreateClearTex(gl_target, gl_texfmt, gl_format, gl_type, scale_type, texture_width >> xs, texture_height >> ys, 128); if (mipmap_gen) mpglTexParameteri(gl_target, GL_GENERATE_MIPMAP, GL_TRUE); mpglActiveTexture(GL_TEXTURE0); mpglBindTexture(gl_target, 0); } if (is_yuv || custom_prog) { if ((MASK_NOT_COMBINERS & (1 << use_yuv)) || custom_prog) { if (!mpglGenPrograms || !mpglBindProgram) { mp_msg(MSGT_VO, MSGL_ERR, "[gl] fragment program functions missing!\n"); } else { mpglGenPrograms(1, &fragprog); mpglBindProgram(GL_FRAGMENT_PROGRAM, fragprog); } } update_yuvconv(); } resize(d_width, d_height); mpglClearColor( 0.0f,0.0f,0.0f,0.0f ); mpglClear( GL_COLOR_BUFFER_BIT ); if (mpglSwapInterval && swap_interval >= 0) mpglSwapInterval(swap_interval); return 1; }