mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 16:20:11 -04:00
parent
9231694f8f
commit
d284cedbea
@ -112,13 +112,25 @@ init_from(FfmpegVideo *source) {
|
||||
// Check if we got an alpha format. Please note that some video codecs
|
||||
// (eg. libvpx) change the pix_fmt after decoding the first frame, which is
|
||||
// why we didn't do this earlier.
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(_video_ctx->pix_fmt);
|
||||
if (desc && (desc->flags & AV_PIX_FMT_FLAG_ALPHA) != 0) {
|
||||
_num_components = 4;
|
||||
_pixel_format = (int)AV_PIX_FMT_BGRA;
|
||||
} else {
|
||||
_num_components = 3;
|
||||
_pixel_format = (int)AV_PIX_FMT_BGR24;
|
||||
switch (_video_ctx->pix_fmt) {
|
||||
case AV_PIX_FMT_GRAY8:
|
||||
_num_components = 1;
|
||||
_pixel_format = (int)AV_PIX_FMT_GRAY8;
|
||||
break;
|
||||
case AV_PIX_FMT_YA8:
|
||||
_num_components = 2;
|
||||
_pixel_format = (int)AV_PIX_FMT_YA8;
|
||||
break;
|
||||
default:
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(_video_ctx->pix_fmt);
|
||||
if (desc && (desc->flags & AV_PIX_FMT_FLAG_ALPHA) != 0) {
|
||||
_num_components = 4;
|
||||
_pixel_format = (int)AV_PIX_FMT_BGRA;
|
||||
} else {
|
||||
_num_components = 3;
|
||||
_pixel_format = (int)AV_PIX_FMT_BGR24;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SWSCALE
|
||||
|
@ -141,6 +141,7 @@ void MovieTexture::
|
||||
do_recalculate_image_properties(CData *cdata, Texture::CData *cdata_tex, const LoaderOptions &options) {
|
||||
int x_max = 1;
|
||||
int y_max = 1;
|
||||
bool rgb = false;
|
||||
bool alpha = false;
|
||||
double len = 0.0;
|
||||
|
||||
@ -150,7 +151,8 @@ do_recalculate_image_properties(CData *cdata, Texture::CData *cdata_tex, const L
|
||||
if (t->size_x() > x_max) x_max = t->size_x();
|
||||
if (t->size_y() > y_max) y_max = t->size_y();
|
||||
if (t->length() > len) len = t->length();
|
||||
if (t->get_num_components() == 4) alpha=true;
|
||||
if (t->get_num_components() >= 3) rgb=true;
|
||||
if (t->get_num_components() == 4 || t->get_num_components() == 2) alpha=true;
|
||||
}
|
||||
t = cdata->_pages[i]._alpha;
|
||||
if (t) {
|
||||
@ -167,7 +169,8 @@ do_recalculate_image_properties(CData *cdata, Texture::CData *cdata_tex, const L
|
||||
|
||||
do_adjust_this_size(cdata_tex, x_max, y_max, get_name(), true);
|
||||
|
||||
do_reconsider_image_properties(cdata_tex, x_max, y_max, alpha?4:3,
|
||||
int num_components = (rgb ? 3 : 1) + alpha;
|
||||
do_reconsider_image_properties(cdata_tex, x_max, y_max, num_components,
|
||||
T_unsigned_byte, cdata->_pages.size(),
|
||||
options);
|
||||
cdata_tex->_orig_file_x_size = cdata->_video_width;
|
||||
|
@ -60,7 +60,21 @@ setup_texture(Texture *tex) const {
|
||||
int fullx = size_x();
|
||||
int fully = size_y();
|
||||
tex->adjust_this_size(fullx, fully, tex->get_name(), true);
|
||||
Texture::Format fmt = (get_num_components() == 4) ? Texture::F_rgba : Texture::F_rgb;
|
||||
Texture::Format fmt;
|
||||
switch (get_num_components()) {
|
||||
case 1:
|
||||
fmt = Texture::F_luminance;
|
||||
break;
|
||||
case 2:
|
||||
fmt = Texture::F_luminance_alpha;
|
||||
break;
|
||||
default:
|
||||
fmt = Texture::F_rgb;
|
||||
break;
|
||||
case 4:
|
||||
fmt = Texture::F_rgba;
|
||||
break;
|
||||
}
|
||||
tex->setup_texture(Texture::TT_2d_texture, fullx, fully, 1, Texture::T_unsigned_byte, fmt);
|
||||
tex->set_pad_size(fullx - size_x(), fully - size_y());
|
||||
}
|
||||
@ -113,7 +127,9 @@ apply_to_texture(const Buffer *buffer, Texture *t, int page) {
|
||||
|
||||
nassertv(t->get_x_size() >= size_x());
|
||||
nassertv(t->get_y_size() >= size_y());
|
||||
nassertv((t->get_num_components() == 3) || (t->get_num_components() == 4));
|
||||
nassertv((t->get_num_components() == 3) || (t->get_num_components() == 4) ||
|
||||
(t->get_num_components() == 1 && get_num_components() == 1) ||
|
||||
(t->get_num_components() == 2 && get_num_components() == 2));
|
||||
nassertv(t->get_component_width() == 1);
|
||||
nassertv(page < t->get_num_pages());
|
||||
|
||||
@ -132,17 +148,19 @@ apply_to_texture(const Buffer *buffer, Texture *t, int page) {
|
||||
|
||||
} else {
|
||||
unsigned char *p = buffer->_block;
|
||||
if (t->get_num_components() == get_num_components()) {
|
||||
int src_stride = size_x() * get_num_components();
|
||||
int dst_stride = t->get_x_size() * t->get_num_components();
|
||||
int src_width = get_num_components();
|
||||
int dst_width = t->get_num_components();
|
||||
if (src_width == dst_width) {
|
||||
int src_stride = src_width * size_x();
|
||||
int dst_stride = dst_width * t->get_x_size();
|
||||
for (int y=0; y<size_y(); y++) {
|
||||
memcpy(data, p, src_stride);
|
||||
data += dst_stride;
|
||||
p += src_stride;
|
||||
}
|
||||
} else {
|
||||
int src_width = get_num_components();
|
||||
int dst_width = t->get_num_components();
|
||||
nassertv(src_width >= 3);
|
||||
nassertv(dst_width >= 3);
|
||||
for (int y = 0; y < size_y(); ++y) {
|
||||
for (int x = 0; x < size_x(); ++x) {
|
||||
data[0] = p[0];
|
||||
@ -168,9 +186,20 @@ apply_to_texture_alpha(const Buffer *buffer, Texture *t, int page, int alpha_src
|
||||
|
||||
PStatTimer timer(_copy_pcollector);
|
||||
|
||||
// Is this a grayscale texture?
|
||||
if (get_num_components() < 3) {
|
||||
if (get_num_components() == 1 || alpha_src < 2 || alpha_src == 3) {
|
||||
// There's only one "RGB" channel to take from.
|
||||
alpha_src = 1;
|
||||
} else {
|
||||
// Alpha is actually in the second channel for grayscale-alpha.
|
||||
alpha_src = 2;
|
||||
}
|
||||
}
|
||||
|
||||
nassertv(t->get_x_size() >= size_x());
|
||||
nassertv(t->get_y_size() >= size_y());
|
||||
nassertv(t->get_num_components() == 4);
|
||||
nassertv(t->get_num_components() == 4 || t->get_num_components() == 2);
|
||||
nassertv(t->get_component_width() == 1);
|
||||
nassertv(page < t->get_z_size());
|
||||
nassertv((alpha_src >= 0) && (alpha_src <= get_num_components()));
|
||||
@ -186,14 +215,16 @@ apply_to_texture_alpha(const Buffer *buffer, Texture *t, int page, int alpha_src
|
||||
|
||||
PStatTimer timer2(_copy_pcollector_copy);
|
||||
int src_width = get_num_components();
|
||||
int dst_width = t->get_num_components();
|
||||
int src_stride = size_x() * src_width;
|
||||
int dst_stride = t->get_x_size() * 4;
|
||||
int dst_stride = t->get_x_size() * dst_width;
|
||||
unsigned char *p = buffer->_block;
|
||||
if (alpha_src == 0) {
|
||||
nassertv(src_width >= 3);
|
||||
for (int y=0; y<size_y(); y++) {
|
||||
for (int x=0; x<size_x(); x++) {
|
||||
unsigned char *pp = &p[x * src_width];
|
||||
data[x*4+3] = (pp[0] + pp[1] + pp[2]) / 3;
|
||||
data[(x + 1) * dst_width - 1] = (pp[0] + pp[1] + pp[2]) / 3;
|
||||
}
|
||||
data += dst_stride;
|
||||
p += src_stride;
|
||||
@ -202,7 +233,7 @@ apply_to_texture_alpha(const Buffer *buffer, Texture *t, int page, int alpha_src
|
||||
alpha_src -= 1;
|
||||
for (int y=0; y<size_y(); y++) {
|
||||
for (int x=0; x<size_x(); x++) {
|
||||
data[x*4+3] = p[x * src_width + alpha_src];
|
||||
data[(x + 1) * dst_width - 1] = p[x * src_width + alpha_src];
|
||||
}
|
||||
data += dst_stride;
|
||||
p += src_stride;
|
||||
@ -224,7 +255,7 @@ apply_to_texture_rgb(const Buffer *buffer, Texture *t, int page) {
|
||||
|
||||
nassertv(t->get_x_size() >= size_x());
|
||||
nassertv(t->get_y_size() >= size_y());
|
||||
nassertv(t->get_num_components() == 4);
|
||||
nassertv(t->get_num_components() == 4 || t->get_num_components() == 2);
|
||||
nassertv(t->get_component_width() == 1);
|
||||
nassertv(page < t->get_z_size());
|
||||
|
||||
@ -238,18 +269,35 @@ apply_to_texture_rgb(const Buffer *buffer, Texture *t, int page) {
|
||||
unsigned char *data = img.p() + page * t->get_expected_ram_page_size();
|
||||
|
||||
PStatTimer timer2(_copy_pcollector_copy);
|
||||
int src_stride = size_x() * get_num_components();
|
||||
int src_width = get_num_components();
|
||||
int dst_stride = t->get_x_size() * 4;
|
||||
int dst_width = t->get_num_components();
|
||||
int src_stride = size_x() * src_width;
|
||||
int dst_stride = t->get_x_size() * dst_width;
|
||||
unsigned char *p = buffer->_block;
|
||||
for (int y=0; y<size_y(); y++) {
|
||||
for (int x=0; x<size_x(); x++) {
|
||||
data[x * 4 + 0] = p[x * src_width + 0];
|
||||
data[x * 4 + 1] = p[x * src_width + 1];
|
||||
data[x * 4 + 2] = p[x * src_width + 2];
|
||||
if (src_width >= 3) {
|
||||
// It has RGB values.
|
||||
nassertv(dst_width >= 3);
|
||||
for (int y = 0; y < size_y(); ++y) {
|
||||
for (int x = 0; x < size_x(); ++x) {
|
||||
data[x * dst_width + 0] = p[x * src_width + 0];
|
||||
data[x * dst_width + 1] = p[x * src_width + 1];
|
||||
data[x * dst_width + 2] = p[x * src_width + 2];
|
||||
}
|
||||
data += dst_stride;
|
||||
p += src_stride;
|
||||
}
|
||||
} else if (dst_width == 4) {
|
||||
// It has only grayscale.
|
||||
for (int y = 0; y < size_y(); ++y) {
|
||||
for (int x = 0; x < size_x(); ++x) {
|
||||
unsigned char gray = p[x * src_width];
|
||||
data[x * dst_width + 0] = gray;
|
||||
data[x * dst_width + 1] = gray;
|
||||
data[x * dst_width + 2] = gray;
|
||||
}
|
||||
data += dst_stride;
|
||||
p += src_stride;
|
||||
}
|
||||
data += dst_stride;
|
||||
p += src_stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user