📄 texturing_gl.c
字号:
case GF_PIXEL_GREYSCALE: case GF_PIXEL_ALPHAGREY: case GF_PIXEL_RGB_24: case GF_PIXEL_RGB_32: case GF_PIXEL_RGBA: if (txh->stream && !(gf_mo_get_flags(txh->stream) & GF_MO_IS_FLIP) ) { u32 i, hy; char *tmp; /*flip image*/ tmp = (char*)malloc(sizeof(char)*txh->stride); hy = txh->height/2; for (i=0; i<hy; i++) { memcpy(tmp, txh->data + i*txh->stride, txh->stride); memcpy(txh->data + i*txh->stride, txh->data + (txh->height - 1 - i) * txh->stride, txh->stride); memcpy(txh->data + (txh->height - 1 - i) * txh->stride, tmp, txh->stride); } free(tmp); gf_mo_set_flag(txh->stream, GF_MO_IS_FLIP, 1); } gltx->conv_format = txh->pixelformat; gltx->tx_flags |= TX_NEEDS_HW_LOAD; return 1; case GF_PIXEL_YV12: break; default: gltx->conv_format = 0; return 0; } if (!gltx->conv_data) { if (gltx->tx_flags == TX_EMULE_POW2) { /*convert video to a po of 2 WITHOUT SCALING VIDEO*/ gltx->conv_w = get_next_pow2(txh->width); gltx->conv_h = get_next_pow2(txh->height); gltx->conv_data = (char*)malloc(sizeof(char) * 3 * gltx->conv_w * gltx->conv_h); memset(gltx->conv_data , 0, sizeof(char) * 3 * gltx->conv_w * gltx->conv_h); gltx->conv_wscale = INT2FIX(txh->width) / gltx->conv_w; gltx->conv_hscale = INT2FIX(txh->height) / gltx->conv_h; } else { gltx->conv_data = (char*)malloc(sizeof(char) * 3 * txh->width * txh->height); } } out_stride = 3 * ((gltx->tx_flags & TX_EMULE_POW2) ? gltx->conv_w : txh->width); dst.width = src.width = txh->width; dst.height = src.height = txh->height; dst.is_hardware_memory = src.is_hardware_memory = 0; src.pitch = txh->stride; src.pixel_format = txh->pixelformat; src.video_buffer = txh->data; dst.pitch = out_stride; gltx->conv_format = dst.pixel_format = GF_PIXEL_RGB_24; dst.video_buffer = gltx->conv_data; /*stretch and flip*/ gf_stretch_bits(&dst, &src, NULL, NULL, 0, 0xFF, 1, NULL, NULL); gltx->tx_flags |= TX_NEEDS_HW_LOAD; return 1;}Bool tx_set_image(GF_TextureHandler *txh, Bool generate_mipmaps){ char *data; GLint tx_mode; u32 pixel_format, w, h; GLTexture *gltx = (GLTexture *) txh->hwtx; if (! (gltx->tx_flags & TX_NEEDS_HW_LOAD) ) return 1; if (!gltx->gl_type) return 0; /*in case the ID has been lost, resetup*/ if (!gltx->id) { glGenTextures(1, &gltx->id); tx_setup_format(txh); } tx_bind(txh); gltx->tx_flags &= ~TX_NEEDS_HW_LOAD; data = tx_get_data(txh, &pixel_format); if (!data) return 0; if (gltx->tx_flags & TX_EMULE_POW2) { w = gltx->conv_w; h = gltx->conv_h; } else { w = txh->width; h = txh->height; } tx_mode = gltx->nb_comp;#ifdef GPAC_USE_OGL_ES tx_mode = gltx->gl_format;#endif /*pow2 texture or hardware support*/ if (! (gltx->tx_flags & TX_MUST_SCALE) ) { if (gltx->first_load) { gltx->first_load = 0; glTexImage2D(gltx->gl_type, 0, tx_mode, w, h, 0, gltx->gl_format, GL_UNSIGNED_BYTE, (unsigned char *) data); } else { glTexSubImage2D(gltx->gl_type, 0, 0, 0, w, h, gltx->gl_format, GL_UNSIGNED_BYTE, (unsigned char *) data); } } else {#ifdef GPAC_USE_OGL_ES GF_VideoSurface src, dst; src.width = txh->width; src.height = txh->height; src.pitch = txh->stride; src.pixel_format = txh->pixelformat; src.video_buffer = txh->data; dst.width = gltx->rescale_width; dst.height = gltx->rescale_height; dst.pitch = gltx->rescale_width*gltx->nb_comp; dst.pixel_format = txh->pixelformat; dst.video_buffer = gltx->scale_data; gf_stretch_bits(&dst, &src, NULL, NULL, 0, 0xFF, 0, NULL, NULL);#else gluScaleImage(gltx->gl_format, txh->width, txh->height, GL_UNSIGNED_BYTE, data, gltx->rescale_width, gltx->rescale_height, GL_UNSIGNED_BYTE, gltx->scale_data);#endif if (gltx->first_load) { gltx->first_load = 0; glTexImage2D(gltx->gl_type, 0, tx_mode, gltx->rescale_width, gltx->rescale_height, 0, gltx->gl_format, GL_UNSIGNED_BYTE, gltx->scale_data); } else { glTexSubImage2D(gltx->gl_type, 0, 0, 0, gltx->rescale_width, gltx->rescale_height, gltx->gl_format, GL_UNSIGNED_BYTE, gltx->scale_data); } } return 1;}void tx_copy_to_texture(GF_TextureHandler *txh){ GLTexture *gltx = (GLTexture *) txh->hwtx; tx_bind(txh); glCopyTexImage2D(gltx->gl_type, 0, gltx->gl_format, 0, 0, txh->width, txh->height, 0); glDisable(gltx->gl_type);}Bool tx_get_transform(GF_TextureHandler *txh, GF_Node *tx_transform, GF_Matrix *mx){ GF_Matrix tmp; Bool ret = 0; GLTexture *gltx = (GLTexture *)txh->hwtx; gf_mx_init(*mx); /*WATCHOUT: this may be GL specific (GL_TEXTURE-RECTANGLE coords are w, h not 1.0, 1.0)*/ if (gltx->tx_flags & TX_IS_RECT) { gf_mx_add_scale(mx, INT2FIX(txh->width), INT2FIX(txh->height), FIX_ONE); /*disable any texture transforms when using RECT textures (no repeat) ??*/ /*tx_transform = NULL;*/ ret = 1; } else if (gltx->tx_flags & TX_EMULE_POW2) { gf_mx_add_scale(mx, gltx->conv_wscale, gltx->conv_hscale, FIX_ONE); /*disable any texture transforms when emulating pow2 textures*/ tx_transform = NULL; ret = 1; } if (tx_transform) { switch (gf_node_get_tag(tx_transform)) { case TAG_MPEG4_TextureTransform: case TAG_X3D_TextureTransform: { GF_Matrix2D mat; M_TextureTransform *tt = (M_TextureTransform *)tx_transform; gf_mx2d_init(mat); /*1- translate*/ gf_mx2d_add_translation(&mat, tt->translation.x, tt->translation.y); /*2- rotate*/ if (fabs(tt->rotation) > FIX_EPSILON) gf_mx2d_add_rotation(&mat, tt->center.x, tt->center.y, tt->rotation); /*3- centered-scale*/ gf_mx2d_add_translation(&mat, -tt->center.x, -tt->center.y); gf_mx2d_add_scale(&mat, tt->scale.x, tt->scale.y); gf_mx2d_add_translation(&mat, tt->center.x, tt->center.y); if (ret) { gf_mx_from_mx2d(&tmp, &mat); gf_mx_add_matrix(mx, &tmp); } else { gf_mx_from_mx2d(mx, &mat); } ret = 1; } break; case TAG_MPEG4_TransformMatrix2D: { M_TransformMatrix2D *tm = (M_TransformMatrix2D *)tx_transform; memset(tmp.m, 0, sizeof(Fixed)*16); tmp.m[0] = tm->mxx; tmp.m[4] = tm->mxy; /*0*/ tmp.m[12] = tm->tx; tmp.m[1] = tm->myx; tmp.m[5] = tm->myy; /*0*/ tmp.m[13] = tm->ty; /*rest is all 0 excep both diag*/ tmp.m[10] = tmp.m[15] = FIX_ONE; if (ret) { gf_mx_add_matrix(mx, &tmp); } else { gf_mx_copy(*mx, tmp); } ret = 1; } break; default: break; } } return ret;}static Bool tx_enable_matte_texture(GF_Node *n){/* GF_TextureHandler *b_surf; GF_TextureHandler *a_surf; GF_TextureHandler *alpha_surf; M_MatteTexture *matte = (M_MatteTexture *)n; b_surf = R3D_GetTextureHandler(matte->surfaceB); if (!b_surf || !b_surf->hwtx) return 0; tx_set_image(b_surf, 0); tx_bind(b_surf); a_surf = R3D_GetTextureHandler(matte->surfaceA); alpha_surf = R3D_GetTextureHandler(matte->alphaSurface); if (!alpha_surf || !alpha_surf->hwtx) return 0; tx_set_image(alpha_surf, 0); tx_bind_with_mode(alpha_surf, tx_is_transparent(b_surf), ((GLTexture *)b_surf->hwtx)->blend_mode); return 1;*/ return 0;}Bool tx_is_transparent(GF_TextureHandler *txh){ M_MatteTexture *matte; if (!txh->matteTexture) return txh->transparent; matte = (M_MatteTexture *)txh->matteTexture; if (!matte->operation.buffer) return txh->transparent; if (matte->alphaSurface) return 1; if (!strcmp(matte->operation.buffer, "COLOR_MATRIX")) return 1; return txh->transparent;}Bool tx_enable(GF_TextureHandler *txh, GF_Node *tx_transform){ GF_Matrix mx; Render3D *sr = (Render3D *)txh->compositor->visual_renderer->user_priv; if (txh->matteTexture) { if (!tx_enable_matte_texture(txh->matteTexture)) return 0; VS3D_SetMatrixMode(sr->surface, MAT_TEXTURE); if (tx_get_transform(txh, tx_transform, &mx)) VS3D_LoadMatrix(sr->surface, mx.m); else VS3D_ResetMatrix(sr->surface); VS3D_SetMatrixMode(sr->surface, MAT_MODELVIEW); return 1; } if (!txh || !txh->hwtx) return 0; tx_set_image(txh, 0); VS3D_SetMatrixMode(sr->surface, MAT_TEXTURE); if (tx_get_transform(txh, tx_transform, &mx)) VS3D_LoadMatrix(sr->surface, mx.m); else VS3D_ResetMatrix(sr->surface); VS3D_SetMatrixMode(sr->surface, MAT_MODELVIEW); tx_bind(txh); return 1;}GF_Err R3D_SetTextureData(GF_TextureHandler *hdl){ GLTexture *gltx = (GLTexture *)hdl->hwtx; /*init if needed*/ if (!gltx->gl_type) { if (!tx_setup_format(hdl)) return GF_NOT_SUPPORTED; } /*convert image - don't push it to HW until used*/ tx_convert(hdl); return GF_OK;}void R3D_TextureHWReset(GF_TextureHandler *hdl){ GLTexture *gltx = (GLTexture *)hdl->hwtx; if (gltx->id) { glDeleteTextures(1, &gltx->id); gltx->id = 0; } gltx->tx_flags |= TX_NEEDS_HW_LOAD;}Bool tx_needs_reload(GF_TextureHandler *hdl){ return ( ((GLTexture *)hdl->hwtx)->tx_flags & TX_NEEDS_HW_LOAD ) ? 1 : 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -