mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
change normal texture byte ordering from RGBA to BGRA (big-endian)
This commit is contained in:
parent
eb0f572b3b
commit
e71491040f
@ -65,6 +65,11 @@ bool gl_save_mipmaps = config_glgsg.GetBool("gl-save-mipmaps", false);
|
||||
// variable.
|
||||
bool gl_auto_normalize_lighting = config_glgsg.GetBool("auto-normalize-lighting", false);
|
||||
|
||||
// Configure this true to indicate the current version of GL fully
|
||||
// supports textures with B, G, R ordering; false if it only supports
|
||||
// R, G, B.
|
||||
bool gl_supports_bgr = config_glgsg.GetBool("gl-supports-bgr", true);
|
||||
|
||||
GLDecalType gl_decal_type = GDT_offset;
|
||||
|
||||
static GLDecalType
|
||||
|
@ -30,8 +30,9 @@ extern bool gl_cull_traversal;
|
||||
extern bool gl_ignore_mipmaps;
|
||||
extern bool gl_force_mipmaps;
|
||||
extern bool gl_show_mipmaps;
|
||||
extern bool gl_auto_normalize_lighting;
|
||||
extern bool gl_save_mipmaps;
|
||||
extern bool gl_auto_normalize_lighting;
|
||||
extern bool gl_supports_bgr;
|
||||
|
||||
// Ways to implement decals.
|
||||
enum GLDecalType {
|
||||
|
@ -2223,9 +2223,15 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
|
||||
case GL_DEPTH_COMPONENT:
|
||||
glgsg_cat.debug(false) << "GL_DEPTH_COMPONENT, ";
|
||||
break;
|
||||
case GL_BGR:
|
||||
glgsg_cat.debug(false) << "GL_BGR, ";
|
||||
break;
|
||||
case GL_RGB:
|
||||
glgsg_cat.debug(false) << "GL_RGB, ";
|
||||
break;
|
||||
case GL_BGRA:
|
||||
glgsg_cat.debug(false) << "GL_BGRA, ";
|
||||
break;
|
||||
case GL_RGBA:
|
||||
glgsg_cat.debug(false) << "GL_RGBA, ";
|
||||
break;
|
||||
@ -2350,9 +2356,15 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
|
||||
case GL_DEPTH_COMPONENT:
|
||||
glgsg_cat.debug(false) << "GL_DEPTH_COMPONENT, ";
|
||||
break;
|
||||
case GL_BGR:
|
||||
glgsg_cat.debug(false) << "GL_BGR, ";
|
||||
break;
|
||||
case GL_RGB:
|
||||
glgsg_cat.debug(false) << "GL_RGB, ";
|
||||
break;
|
||||
case GL_BGRA:
|
||||
glgsg_cat.debug(false) << "GL_BGRA, ";
|
||||
break;
|
||||
case GL_RGBA:
|
||||
glgsg_cat.debug(false) << "GL_RGBA, ";
|
||||
break;
|
||||
@ -3784,10 +3796,12 @@ compute_gl_image_size(int xsize, int ysize, int external_format, int type) {
|
||||
num_components = 2;
|
||||
break;
|
||||
|
||||
case GL_BGR:
|
||||
case GL_RGB:
|
||||
num_components = 3;
|
||||
break;
|
||||
|
||||
case GL_BGRA:
|
||||
case GL_RGBA:
|
||||
num_components = 4;
|
||||
break;
|
||||
@ -3819,6 +3833,40 @@ compute_gl_image_size(int xsize, int ysize, int external_format, int type) {
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::uchar_bgr_to_rgb
|
||||
// Description: Recopies the given array of pixels, converting from
|
||||
// BGR to RGB arrangement.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
static void
|
||||
uchar_bgr_to_rgb(unsigned char *dest, const unsigned char *source,
|
||||
int num_pixels) {
|
||||
for (int i = 0; i < num_pixels; i++) {
|
||||
dest[0] = source[2];
|
||||
dest[1] = source[1];
|
||||
dest[2] = source[0];
|
||||
dest += 3;
|
||||
source += 3;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::uchar_bgra_to_rgba
|
||||
// Description: Recopies the given array of pixels, converting from
|
||||
// BGRA to RGBA arrangement.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
static void
|
||||
uchar_bgra_to_rgba(unsigned char *dest, const unsigned char *source,
|
||||
int num_pixels) {
|
||||
for (int i = 0; i < num_pixels; i++) {
|
||||
dest[0] = source[2];
|
||||
dest[1] = source[1];
|
||||
dest[2] = source[0];
|
||||
dest[3] = source[3];
|
||||
dest += 4;
|
||||
source += 4;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::apply_texture_immediate
|
||||
@ -3837,13 +3885,30 @@ apply_texture_immediate(Texture *tex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int xsize = pb->get_xsize();
|
||||
int ysize = pb->get_ysize();
|
||||
int num_pixels = xsize * ysize;
|
||||
|
||||
GLenum internal_format = get_internal_image_format(pb->get_format());
|
||||
GLenum external_format = get_external_image_format(pb->get_format());
|
||||
GLenum type = get_image_type(pb->get_image_type());
|
||||
|
||||
uchar *image = pb->_image;
|
||||
if (!gl_supports_bgr) {
|
||||
// If the GL doesn't claim to support BGR, we may have to reverse
|
||||
// the byte ordering of the image.
|
||||
if (external_format == GL_RGB && pb->get_image_type() == PixelBuffer::T_unsigned_byte) {
|
||||
image = (uchar *)alloca(num_pixels * 3);
|
||||
uchar_bgr_to_rgb(image, pb->_image, num_pixels);
|
||||
} else if (external_format == GL_RGBA && pb->get_image_type() == PixelBuffer::T_unsigned_byte) {
|
||||
image = (uchar *)alloca(num_pixels * 4);
|
||||
uchar_bgra_to_rgba(image, pb->_image, num_pixels);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
int wanted_size =
|
||||
compute_gl_image_size(pb->get_xsize(), pb->get_ysize(),
|
||||
compute_gl_image_size(xsize, ysize,
|
||||
external_format, type);
|
||||
nassertr(wanted_size == (int)pb->_image.size(), false);
|
||||
#endif // NDEBUG
|
||||
@ -3854,7 +3919,7 @@ apply_texture_immediate(Texture *tex) {
|
||||
glgsg_cat.debug()
|
||||
<< "glTexImage2D(GL_TEXTURE_2D, "
|
||||
<< (int)internal_format << ", "
|
||||
<< pb->get_xsize() << ", " << pb->get_ysize() << ", "
|
||||
<< xsize << ", " << ysize << ", "
|
||||
<< pb->get_border() << ", " << (int)external_format << ", "
|
||||
<< (int)type << ", " << tex->get_name() << ")\n";
|
||||
#endif
|
||||
@ -3868,8 +3933,8 @@ apply_texture_immediate(Texture *tex) {
|
||||
}
|
||||
#endif
|
||||
gluBuild2DMipmaps(GL_TEXTURE_2D, internal_format,
|
||||
pb->get_xsize(), pb->get_ysize(),
|
||||
external_format, type, pb->_image);
|
||||
xsize, ysize,
|
||||
external_format, type, image);
|
||||
#ifndef NDEBUG
|
||||
if (gl_save_mipmaps) {
|
||||
save_mipmap_images(tex);
|
||||
@ -3882,8 +3947,8 @@ apply_texture_immediate(Texture *tex) {
|
||||
|
||||
nassertr(!pb->_image.empty(), false);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internal_format,
|
||||
pb->get_xsize(), pb->get_ysize(), pb->get_border(),
|
||||
external_format, type, pb->_image);
|
||||
xsize, ysize, pb->get_border(),
|
||||
external_format, type, image);
|
||||
report_errors();
|
||||
return true;
|
||||
}
|
||||
@ -3901,6 +3966,8 @@ get_texture_wrap_mode(Texture::WrapMode wm) {
|
||||
return GL_CLAMP;
|
||||
case Texture::WM_repeat:
|
||||
return GL_REPEAT;
|
||||
case Texture::WM_invalid:
|
||||
break;
|
||||
}
|
||||
glgsg_cat.error() << "Invalid Texture::WrapMode value!\n";
|
||||
return GL_CLAMP;
|
||||
@ -3924,6 +3991,8 @@ get_texture_filter_type(Texture::FilterType ft) {
|
||||
case Texture::FT_nearest_mipmap_linear:
|
||||
case Texture::FT_linear_mipmap_linear:
|
||||
return GL_LINEAR;
|
||||
case Texture::FT_invalid:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (ft) {
|
||||
@ -3939,6 +4008,8 @@ get_texture_filter_type(Texture::FilterType ft) {
|
||||
return GL_NEAREST_MIPMAP_LINEAR;
|
||||
case Texture::FT_linear_mipmap_linear:
|
||||
return GL_LINEAR_MIPMAP_LINEAR;
|
||||
case Texture::FT_invalid:
|
||||
break;
|
||||
}
|
||||
}
|
||||
glgsg_cat.error() << "Invalid Texture::FilterType value!\n";
|
||||
@ -3999,14 +4070,14 @@ get_external_image_format(PixelBuffer::Format format) {
|
||||
case PixelBuffer::F_rgb8:
|
||||
case PixelBuffer::F_rgb12:
|
||||
case PixelBuffer::F_rgb332:
|
||||
return GL_RGB;
|
||||
return gl_supports_bgr ? GL_BGR : GL_RGB;
|
||||
case PixelBuffer::F_rgba:
|
||||
case PixelBuffer::F_rgbm:
|
||||
case PixelBuffer::F_rgba4:
|
||||
case PixelBuffer::F_rgba5:
|
||||
case PixelBuffer::F_rgba8:
|
||||
case PixelBuffer::F_rgba12:
|
||||
return GL_RGBA;
|
||||
return gl_supports_bgr ? GL_BGRA : GL_RGBA;
|
||||
case PixelBuffer::F_luminance:
|
||||
return GL_LUMINANCE;
|
||||
case PixelBuffer::F_luminance_alphamask:
|
||||
@ -4016,7 +4087,7 @@ get_external_image_format(PixelBuffer::Format format) {
|
||||
glgsg_cat.error()
|
||||
<< "Invalid PixelBuffer::Format value in get_external_image_format(): "
|
||||
<< (int)format << "\n";
|
||||
return GL_RGB;
|
||||
return GL_BGR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -168,9 +168,12 @@ bool PixelBuffer::write( const string& name ) const
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: read
|
||||
// Access:
|
||||
// Description:
|
||||
// Function: load
|
||||
// Access: Public
|
||||
// Description: Extracts the image data from the given PNMImage and
|
||||
// stores it in the _image member, as an unadorned array
|
||||
// of pixel values. Note that we now store pixel
|
||||
// components in the order B, G, R, A.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PixelBuffer::load(const PNMImage& pnmimage)
|
||||
{
|
||||
@ -228,9 +231,9 @@ bool PixelBuffer::load(const PNMImage& pnmimage)
|
||||
if (is_grayscale) {
|
||||
store_unscaled_byte(idx, pnmimage.get_gray_val(i, j));
|
||||
} else {
|
||||
store_unscaled_byte(idx, pnmimage.get_red_val(i, j));
|
||||
store_unscaled_byte(idx, pnmimage.get_green_val(i, j));
|
||||
store_unscaled_byte(idx, pnmimage.get_blue_val(i, j));
|
||||
store_unscaled_byte(idx, pnmimage.get_green_val(i, j));
|
||||
store_unscaled_byte(idx, pnmimage.get_red_val(i, j));
|
||||
}
|
||||
if (has_alpha) {
|
||||
store_unscaled_byte(idx, pnmimage.get_alpha_val(i, j));
|
||||
@ -250,9 +253,9 @@ bool PixelBuffer::load(const PNMImage& pnmimage)
|
||||
if (is_grayscale) {
|
||||
store_unscaled_short(idx, pnmimage.get_gray_val(i, j));
|
||||
} else {
|
||||
store_unscaled_short(idx, pnmimage.get_red_val(i, j));
|
||||
store_unscaled_short(idx, pnmimage.get_green_val(i, j));
|
||||
store_unscaled_short(idx, pnmimage.get_blue_val(i, j));
|
||||
store_unscaled_short(idx, pnmimage.get_green_val(i, j));
|
||||
store_unscaled_short(idx, pnmimage.get_red_val(i, j));
|
||||
}
|
||||
if (has_alpha) {
|
||||
store_unscaled_short(idx, pnmimage.get_alpha_val(i, j));
|
||||
@ -274,9 +277,9 @@ bool PixelBuffer::load(const PNMImage& pnmimage)
|
||||
if (is_grayscale) {
|
||||
store_scaled_byte(idx, pnmimage.get_gray_val(i, j), scale);
|
||||
} else {
|
||||
store_scaled_byte(idx, pnmimage.get_red_val(i, j), scale);
|
||||
store_scaled_byte(idx, pnmimage.get_green_val(i, j), scale);
|
||||
store_scaled_byte(idx, pnmimage.get_blue_val(i, j), scale);
|
||||
store_scaled_byte(idx, pnmimage.get_green_val(i, j), scale);
|
||||
store_scaled_byte(idx, pnmimage.get_red_val(i, j), scale);
|
||||
}
|
||||
if (has_alpha) {
|
||||
store_scaled_byte(idx, pnmimage.get_alpha_val(i, j), scale);
|
||||
@ -298,9 +301,9 @@ bool PixelBuffer::load(const PNMImage& pnmimage)
|
||||
if (is_grayscale) {
|
||||
store_scaled_short(idx, pnmimage.get_gray_val(i, j), scale);
|
||||
} else {
|
||||
store_scaled_short(idx, pnmimage.get_red_val(i, j), scale);
|
||||
store_scaled_short(idx, pnmimage.get_green_val(i, j), scale);
|
||||
store_scaled_short(idx, pnmimage.get_blue_val(i, j), scale);
|
||||
store_scaled_short(idx, pnmimage.get_green_val(i, j), scale);
|
||||
store_scaled_short(idx, pnmimage.get_red_val(i, j), scale);
|
||||
}
|
||||
if (has_alpha) {
|
||||
store_scaled_short(idx, pnmimage.get_alpha_val(i, j), scale);
|
||||
@ -332,9 +335,9 @@ store(PNMImage &pnmimage) const {
|
||||
if (is_grayscale) {
|
||||
pnmimage.set_gray(i, j, get_unsigned_byte(idx));
|
||||
} else {
|
||||
pnmimage.set_red(i, j, get_unsigned_byte(idx));
|
||||
pnmimage.set_green(i, j, get_unsigned_byte(idx));
|
||||
pnmimage.set_blue(i, j, get_unsigned_byte(idx));
|
||||
pnmimage.set_green(i, j, get_unsigned_byte(idx));
|
||||
pnmimage.set_red(i, j, get_unsigned_byte(idx));
|
||||
}
|
||||
if (has_alpha)
|
||||
pnmimage.set_alpha(i, j, get_unsigned_byte(idx));
|
||||
@ -353,9 +356,9 @@ store(PNMImage &pnmimage) const {
|
||||
if (is_grayscale) {
|
||||
pnmimage.set_gray(i, j, get_unsigned_short(idx));
|
||||
} else {
|
||||
pnmimage.set_red(i, j, get_unsigned_short(idx));
|
||||
pnmimage.set_green(i, j, get_unsigned_short(idx));
|
||||
pnmimage.set_blue(i, j, get_unsigned_short(idx));
|
||||
pnmimage.set_green(i, j, get_unsigned_short(idx));
|
||||
pnmimage.set_red(i, j, get_unsigned_short(idx));
|
||||
}
|
||||
if (has_alpha)
|
||||
pnmimage.set_alpha(i, j, get_unsigned_short(idx));
|
||||
|
@ -38,6 +38,18 @@ class RenderBuffer;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PixelBuffer
|
||||
// Description :
|
||||
|
||||
// Maintains an array of pixel data corresponding to an
|
||||
// image, e.g. copied from the frame buffer, or as part
|
||||
// of a Texture.
|
||||
|
||||
// Pixel data is stored in a generic, uncompressed
|
||||
// format. Each row of pixels is laid out horizontally,
|
||||
// from the top to the bottom, with no padding between
|
||||
// rows. Each pixel consumes one or more bytes,
|
||||
// according to get_component_width(). If the Format
|
||||
// indicates multiple components are present, they are
|
||||
// stored in the order B, G, R, A.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA PixelBuffer : public ImageBuffer {
|
||||
public:
|
||||
|
Loading…
x
Reference in New Issue
Block a user