clean up texture, projector more

This commit is contained in:
David Rose 2004-07-31 15:49:22 +00:00
parent 5b807d3c0e
commit bccfb40463
12 changed files with 136 additions and 158 deletions

View File

@ -3067,7 +3067,8 @@ copy_texture(Texture *tex, const DisplayRegion *dr) {
dr->get_region_pixels(xo, yo, w, h);
PixelBuffer *pb = tex->_pbuffer;
pb->set_size(0,0,w-xo,h-yo);
pb->set_xsize(w-xo);
pb->set_ysize(h-yo);
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
if (tc == (TextureContext *)NULL) {

View File

@ -3065,7 +3065,8 @@ copy_texture(Texture *tex, const DisplayRegion *dr) {
dr->get_region_pixels(xo, yo, w, h);
PixelBuffer *pb = tex->_pbuffer;
pb->set_size(0,0,w-xo,h-yo);
pb->set_xsize(w-xo);
pb->set_ysize(h-yo);
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
if (tc == (TextureContext *)NULL) {

View File

@ -341,6 +341,27 @@ reset() {
_edge_clamp = GL_CLAMP_TO_EDGE;
}
_border_clamp = GL_CLAMP;
if (has_extension("GL_ARB_texture_border_clamp") ||
is_at_least_version(1, 3)) {
_border_clamp = GL_CLAMP_TO_BORDER;
}
_mirror_repeat = GL_REPEAT;
if (has_extension("GL_ARB_texture_mirrored_repeat") ||
is_at_least_version(1, 4)) {
_mirror_repeat = GL_MIRRORED_REPEAT;
}
_mirror_clamp = GL_CLAMP;
_mirror_edge_clamp = _edge_clamp;
_mirror_border_clamp = _border_clamp;
if (has_extension("GL_EXT_texture_mirror_clamp")) {
_mirror_clamp = GL_MIRROR_CLAMP_EXT;
_mirror_edge_clamp = GL_MIRROR_CLAMP_TO_EDGE_EXT;
_mirror_border_clamp = GL_MIRROR_CLAMP_TO_BORDER_EXT;
}
report_my_gl_errors();
_buffer_mask = 0;
@ -1850,11 +1871,11 @@ apply_texture(TextureContext *tc) {
bind_texture(gtc);
int dirty = gtc->get_dirty_flags();
if ((dirty & (Texture::DF_wrap | Texture::DF_filter)) != 0) {
if ((dirty & (Texture::DF_wrap | Texture::DF_filter | Texture::DF_border)) != 0) {
// We need to re-specify the texture properties.
specify_texture(gtc->_texture);
}
if ((dirty & (Texture::DF_image | Texture::DF_mipmap)) != 0) {
if ((dirty & (Texture::DF_image | Texture::DF_mipmap | Texture::DF_border)) != 0) {
// We need to re-apply the image.
apply_texture_immediate(gtc, gtc->_texture);
}
@ -2035,7 +2056,8 @@ copy_texture(Texture *tex, const DisplayRegion *dr) {
#endif
PixelBuffer *pb = tex->_pbuffer;
pb->set_size(xo,yo,w,h);
pb->set_xsize(w);
pb->set_ysize(h);
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
nassertv(tc != (TextureContext *)NULL);
@ -2043,7 +2065,7 @@ copy_texture(Texture *tex, const DisplayRegion *dr) {
GLP(CopyTexImage2D)(GL_TEXTURE_2D, 0,
get_internal_image_format(pb->get_format()),
xo, yo, w, h, pb->get_border());
xo, yo, w, h, tex->get_border_width());
// Clear the internal texture state, since we've just monkeyed with it.
modify_state(get_untextured_state());
@ -2138,7 +2160,7 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
#ifdef GSG_VERBOSE
GLCAT.debug()
<< "glReadPixels(" << pb->get_xorg() << ", " << pb->get_yorg()
<< "glReadPixels(" << xo << ", " << yo
<< ", " << pb->get_xsize() << ", " << pb->get_ysize()
<< ", ";
switch (external_format) {
@ -2179,11 +2201,11 @@ copy_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
// pixelbuffer "origin" represents upper left screen point at which
// pixelbuffer should be drawn using draw_pixel_buffer
nassertr(!pb->_image.empty(), false);
GLP(ReadPixels)(pb->get_xorg() + xo, pb->get_yorg() + yo,
pb->get_xsize(), pb->get_ysize(),
external_format,
get_image_type(pb->get_image_type()),
pb->_image.p());
GLP(ReadPixels)(xo, yo,
pb->get_xsize(), pb->get_ysize(),
external_format,
get_image_type(pb->get_image_type()),
pb->_image.p());
// We may have to reverse the byte ordering of the image if GL
// didn't do it for us.
@ -3207,6 +3229,10 @@ specify_texture(Texture *tex) {
GLP(TexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
get_texture_wrap_mode(tex->get_wrapv()));
Colorf border_color = tex->get_border_color();
GLP(TexParameterfv)(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR,
border_color.get_data());
Texture::FilterType minfilter = tex->get_minfilter();
Texture::FilterType magfilter = tex->get_magfilter();
@ -3336,7 +3362,7 @@ apply_texture_immediate(CLP(TextureContext) *gtc, Texture *tex) {
<< "glTexImage2D(GL_TEXTURE_2D, "
<< (int)internal_format << ", "
<< width << ", " << height << ", "
<< pb->get_border() << ", " << (int)external_format << ", "
<< tex->get_border_width() << ", " << (int)external_format << ", "
<< (int)type << ", " << tex->get_name() << ")\n";
#endif
@ -3371,7 +3397,7 @@ apply_texture_immediate(CLP(TextureContext) *gtc, Texture *tex) {
gtc->_internal_format = internal_format;
gtc->_width = width;
gtc->_height = height;
gtc->_border = 0;
gtc->_border_width = 0;
#ifndef NDEBUG
if (CLP(save_mipmaps)) {
@ -3387,22 +3413,22 @@ apply_texture_immediate(CLP(TextureContext) *gtc, Texture *tex) {
}
}
GLint border = pb->get_border();
GLint border_width = tex->get_border_width();
if (!gtc->_already_applied ||
gtc->_internal_format != internal_format ||
gtc->_width != width ||
gtc->_height != height ||
gtc->_border != border) {
gtc->_border_width != border_width) {
// We need to reload a new image.
GLP(TexImage2D)(GL_TEXTURE_2D, 0, internal_format,
width, height, pb->get_border(),
width, height, border_width,
external_format, type, image);
gtc->_already_applied = true;
gtc->_internal_format = internal_format;
gtc->_width = width;
gtc->_height = height;
gtc->_border = border;
gtc->_border_width = border_width;
} else {
// We can reload the image over the previous image, saving on
@ -3623,11 +3649,11 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr) {
<< (void *)pb->_image.p() << ")" << endl;
#endif
GLP(RasterPos2i)( pb->get_xorg(), pb->get_yorg() );
GLP(DrawPixels)( pb->get_xsize(), pb->get_ysize(),
get_external_image_format(pb->get_format()),
get_image_type(pb->get_image_type()),
pb->_image.p() );
GLP(RasterPos2i)(0, 0);
GLP(DrawPixels)(pb->get_xsize(), pb->get_ysize(),
get_external_image_format(pb->get_format()),
get_image_type(pb->get_image_type()),
pb->_image.p() );
GLP(MatrixMode)( GL_PROJECTION );
GLP(PopMatrix)();
@ -3663,14 +3689,18 @@ get_texture_wrap_mode(Texture::WrapMode wm) {
switch (wm) {
case Texture::WM_clamp:
return _edge_clamp;
case Texture::WM_repeat:
return GL_REPEAT;
case Texture::WM_mirror:
return _mirror_repeat;
case Texture::WM_mirror_once:
return _mirror_border_clamp;
case Texture::WM_border_color:
// These are unsupported for now.
return GL_REPEAT;
return _border_clamp;
case Texture::WM_invalid:
break;
@ -4684,7 +4714,7 @@ build_phony_mipmap_level(int level, int xsize, int ysize) {
GLenum type = get_image_type(pb->get_image_type());
GLP(TexImage2D)(GL_TEXTURE_2D, level, internal_format,
pb->get_xsize(), pb->get_ysize(), pb->get_border(),
pb->get_xsize(), pb->get_ysize(), 0,
external_format, type, pb->_image );
delete pb;

View File

@ -337,6 +337,11 @@ public:
PFNGLMULTITEXCOORD2FVPROC _glMultiTexCoord2fv;
GLenum _edge_clamp;
GLenum _border_clamp;
GLenum _mirror_repeat;
GLenum _mirror_clamp;
GLenum _mirror_edge_clamp;
GLenum _mirror_border_clamp;
public:
static GraphicsStateGuardian *

View File

@ -40,7 +40,7 @@ public:
GLint _internal_format;
GLsizei _width;
GLsizei _height;
GLint _border;
GLint _border_width;
public:
static TypeHandle get_class_type() {

View File

@ -97,63 +97,6 @@ INLINE void PixelBuffer::set_ysize(int size)
}
}
////////////////////////////////////////////////////////////////////
// Function: PixelBuffer::set_xorg
// Access:
// Description:
////////////////////////////////////////////////////////////////////
INLINE void PixelBuffer::set_xorg(int org)
{
if (_xorg != org) {
_xorg = org;
make_dirty();
}
}
////////////////////////////////////////////////////////////////////
// Function: PixelBuffer::set_yorg
// Access:
// Description:
////////////////////////////////////////////////////////////////////
INLINE void PixelBuffer::set_yorg(int org)
{
if (_yorg != org) {
_yorg = org;
make_dirty();
}
}
////////////////////////////////////////////////////////////////////
// Function: PixelBuffer::set_size
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void PixelBuffer::
set_size(int x_org, int y_org, int x_size, int y_size) {
if ((_xsize != x_size) || (_ysize != y_size) ||
(_xorg != x_org) || (_yorg != y_org)) {
make_dirty();
}
_xsize = x_size;
_ysize = y_size;
_xorg = x_org;
_yorg = y_org;
}
////////////////////////////////////////////////////////////////////
// Function: PixelBuffer::set_border
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void PixelBuffer::
set_border(int border) {
if (_border != border) {
_border = border;
make_dirty();
}
}
////////////////////////////////////////////////////////////////////
// Function: PixelBuffer::set_num_components
// Access: Public
@ -236,37 +179,6 @@ get_ysize() const {
return _ysize;
}
////////////////////////////////////////////////////////////////////
// Function: PixelBuffer::get_xorg
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int PixelBuffer::
get_xorg() const {
return _xorg;
}
////////////////////////////////////////////////////////////////////
// Function: PixelBuffer::get_yorg
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int PixelBuffer::
get_yorg() const {
return _yorg;
}
////////////////////////////////////////////////////////////////////
// Function: PixelBuffer::get_border
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int PixelBuffer::
get_border() const {
return _border;
}
////////////////////////////////////////////////////////////////////
// Function: PixelBuffer::get_num_components
// Access: Public

View File

@ -34,9 +34,6 @@ PixelBuffer(void) : ImageBuffer()
{
_xsize = 0;
_ysize = 0;
_xorg = 0;
_yorg = 0;
_border = 0;
_format = F_rgb;
_type = T_unsigned_byte;
_num_components = 3;
@ -58,9 +55,6 @@ PixelBuffer(int xsize, int ysize, int components, int component_width,
{
_xsize = xsize;
_ysize = ysize;
_xorg = 0;
_yorg = 0;
_border = 0;
_num_components = components;
_component_width = component_width;
_type = type;
@ -80,9 +74,6 @@ PixelBuffer(int xsize, int ysize, int components, int component_width, Type type
{
_xsize = xsize;
_ysize = ysize;
_xorg = 0;
_yorg = 0;
_border = 0;
_num_components = components;
_component_width = component_width;
_type = type;
@ -102,9 +93,6 @@ PixelBuffer::
PixelBuffer(const PixelBuffer &copy) :
_xsize(copy._xsize),
_ysize(copy._ysize),
_xorg(copy._xorg),
_yorg(copy._yorg),
_border(copy._border),
_num_components(copy._num_components),
_component_width(copy._component_width),
_format(copy._format),
@ -123,9 +111,6 @@ void PixelBuffer::
operator = (const PixelBuffer &copy) {
_xsize = copy._xsize;
_ysize = copy._ysize;
_xorg = copy._xorg;
_yorg = copy._yorg;
_border = copy._border;
_num_components = copy._num_components;
_component_width = copy._component_width;
_format = copy._format;
@ -409,11 +394,8 @@ store(PNMImage &pnmimage) const {
void PixelBuffer::
copy(const PixelBuffer *pb) {
nassertv(pb != NULL);
_xorg = pb->_xorg;
_yorg = pb->_yorg;
_xsize = pb->_xsize;
_ysize = pb->_ysize;
_border = pb->_border;
_num_components = pb->_num_components;
_component_width = pb->_component_width;
_format = pb->_format;

View File

@ -108,10 +108,6 @@ public:
INLINE void set_xsize(int size);
INLINE void set_ysize(int size);
INLINE void set_xorg(int org);
INLINE void set_yorg(int org);
INLINE void set_size(int x_org, int y_org, int x_size, int y_size);
INLINE void set_border(int border);
INLINE void set_num_components(int num_components);
INLINE void set_component_width(int component_width);
INLINE void set_format(Format format);
@ -120,9 +116,6 @@ public:
INLINE int get_xsize() const;
INLINE int get_ysize() const;
INLINE int get_xorg() const;
INLINE int get_yorg() const;
INLINE int get_border() const;
INLINE int get_num_components() const;
INLINE int get_component_width() const;
INLINE Format get_format() const;
@ -163,12 +156,6 @@ private:
protected:
int _xsize;
int _ysize;
// pixelbuffer "origin" represents upper left screen point at which
// pixelbuffer should be drawn using draw_pixel_buffer
int _xorg;
int _yorg;
int _border;
int _num_components;
int _component_width;
Format _format;

View File

@ -72,6 +72,26 @@ get_anisotropic_degree() const {
return _anisotropic_degree;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_border_color
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE Colorf Texture::
get_border_color() const {
return _border_color;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_border_width
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int Texture::
get_border_width() const {
return _border_width;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::uses_mipmaps
// Access: Public

View File

@ -142,7 +142,8 @@ Texture() : ImageBuffer() {
_pbuffer = new PixelBuffer;
// _has_requested_size = false;
_all_dirty_flags = 0;
memset(&_border_color,0,sizeof(Colorf));
_border_color.set(0.0f, 0.0f, 0.0f, 1.0f);
_border_width = 0;
}
@ -152,7 +153,8 @@ Texture() : ImageBuffer() {
// Description:
////////////////////////////////////////////////////////////////////
Texture::
Texture(int xsize, int ysize, int components, int component_width, PixelBuffer::Type type,
Texture(int xsize, int ysize, int components, int component_width,
PixelBuffer::Type type,
PixelBuffer::Format format, bool bAllocateRAM) : ImageBuffer() {
_magfilter = FT_linear;
_minfilter = FT_linear;
@ -163,7 +165,8 @@ Texture(int xsize, int ysize, int components, int component_width, PixelBuffer::
_pbuffer = new PixelBuffer(xsize,ysize,components,component_width,type,format,bAllocateRAM);
// _has_requested_size = false;
_all_dirty_flags = 0;
memset(&_border_color,0,sizeof(Colorf));
_border_color.set(0.0f, 0.0f, 0.0f, 1.0f);
_border_width = 0;
}
////////////////////////////////////////////////////////////////////
@ -406,11 +409,33 @@ set_anisotropic_degree(int anisotropic_degree) {
////////////////////////////////////////////////////////////////////
// Function: Texture::set_border_color
// Access: Published
// Description:
// Description: Specifies the uniform color of the texture border, if
// it has one (see set_border_width()), and if the
// border color is not part of the image.
////////////////////////////////////////////////////////////////////
void Texture::
set_border_color(const Colorf &color) {
memcpy(&_border_color,&color,sizeof(Colorf));
if (_border_color != color) {
mark_dirty(DF_border);
_border_color = color;
}
}
////////////////////////////////////////////////////////////////////
// Function: Texture::set_border_width
// Access: Published
// Description: Specifies the width of the texture border, in pixels.
// Generally, this can be either 0 or 1, and the default
// is 0. This is intended to be used for tiling large
// textures, although it has one or two other
// applications.
////////////////////////////////////////////////////////////////////
void Texture::
set_border_width(int width) {
if (_border_width != width) {
mark_dirty(DF_border);
_border_width = width;
}
}
////////////////////////////////////////////////////////////////////
@ -870,9 +895,6 @@ fillin(DatagramIterator &scan, BamReader *manager, bool has_rawdata) {
_pbuffer->set_format(format);
_pbuffer->set_xsize(scan.get_int32());
_pbuffer->set_ysize(scan.get_int32());
_pbuffer->set_xorg(scan.get_int32());
_pbuffer->set_yorg(scan.get_int32());
_pbuffer->set_border(scan.get_uint8());
_pbuffer->set_image_type((PixelBuffer::Type)scan.get_uint8());
_pbuffer->set_num_components(scan.get_uint8());
_pbuffer->set_component_width(scan.get_uint8());
@ -927,9 +949,6 @@ write_datagram(BamWriter *manager, Datagram &me) {
if (has_rawdata) {
me.add_int32(_pbuffer->get_xsize());
me.add_int32(_pbuffer->get_ysize());
me.add_int32(_pbuffer->get_xorg());
me.add_int32(_pbuffer->get_yorg());
me.add_uint8(_pbuffer->get_border());
me.add_uint8(_pbuffer->get_image_type());
me.add_uint8(_pbuffer->get_num_components());
me.add_uint8(_pbuffer->get_component_width());

View File

@ -91,12 +91,15 @@ PUBLISHED:
void set_magfilter(FilterType filter);
void set_anisotropic_degree(int anisotropic_degree);
void set_border_color(const Colorf &color);
void set_border_width(int border_width);
INLINE WrapMode get_wrapu() const;
INLINE WrapMode get_wrapv() const;
INLINE FilterType get_minfilter() const;
INLINE FilterType get_magfilter() const;
INLINE int get_anisotropic_degree() const;
INLINE Colorf get_border_color() const;
INLINE int get_border_width() const;
INLINE bool uses_mipmaps() const;
void prepare(PreparedGraphicsObjects *prepared_objects);
@ -125,6 +128,7 @@ public:
DF_wrap = 0x002, // The wrap properties have changed.
DF_filter = 0x004, // The minfilter or magfilter have changed.
DF_mipmap = 0x008, // The use of mipmaps or not has changed.
DF_border = 0x010, // The border has changed.
};
void mark_dirty(int flags_to_set);
@ -142,6 +146,7 @@ private:
int _anisotropic_degree;
bool _keep_ram_image;
Colorf _border_color;
int _border_width;
// A Texture keeps a list (actually, a map) of all the
// PreparedGraphicsObjects tables that it has been prepared into.

View File

@ -219,7 +219,23 @@ cull_callback(CullTraverser *trav, CullTraverserData &data,
if (def._to_lens_node != (LensNode *)NULL &&
def._to_lens_node->get_lens() != (Lens *)NULL) {
transform = TransformState::make_mat(def._to_lens_node->get_lens()->get_projection_mat())->compose(transform);
// Get the lens's projection matrix, as a TransformState.
CPT(TransformState) projmat = TransformState::make_mat(def._to_lens_node->get_lens()->get_projection_mat());
// We need a special transform to convert the -0.5, 0.5
// centering of the lens's projection matrix to UV's in the
// range of (0, 1).
static CPT(TransformState) fixmat;
if (fixmat == (TransformState *)NULL) {
fixmat = TransformState::make_pos_hpr_scale
(LVecBase3f(0.5f, 0.5f, 0.0f),
LVecBase3f(0.0f, 0.0f, 0.0f),
LVecBase3f(0.5f, 0.5f, 1.0f));
}
// Now apply both to the current transform.
transform = fixmat->compose(projmat)->compose(transform);
}
if (!transform->is_identity()) {