mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-18 12:43:44 -04:00
Add gsg::update_texture()
This commit is contained in:
parent
189626a483
commit
8c2e657f15
@ -414,6 +414,27 @@ prepare_texture(Texture *) {
|
|||||||
return (TextureContext *)NULL;
|
return (TextureContext *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsStateGuardian::update_texture
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Ensures that the current Texture data is refreshed
|
||||||
|
// onto the GSG. This means updating the texture
|
||||||
|
// properties and/or re-uploading the texture image, if
|
||||||
|
// necessary. This should only be called within the
|
||||||
|
// draw thread.
|
||||||
|
//
|
||||||
|
// If force is true, this function will not return until
|
||||||
|
// the texture has been fully uploaded. If force is
|
||||||
|
// false, the function may choose to upload a simple
|
||||||
|
// version of the texture instead, if the texture is not
|
||||||
|
// fully resident (and if get_incomplete_render() is
|
||||||
|
// true).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool GraphicsStateGuardian::
|
||||||
|
update_texture(TextureContext *, bool) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GraphicsStateGuardian::release_texture
|
// Function: GraphicsStateGuardian::release_texture
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -170,6 +170,7 @@ public:
|
|||||||
virtual SceneSetup *get_scene() const;
|
virtual SceneSetup *get_scene() const;
|
||||||
|
|
||||||
virtual TextureContext *prepare_texture(Texture *tex);
|
virtual TextureContext *prepare_texture(Texture *tex);
|
||||||
|
virtual bool update_texture(TextureContext *tc, bool force);
|
||||||
virtual void release_texture(TextureContext *tc);
|
virtual void release_texture(TextureContext *tc);
|
||||||
virtual bool extract_texture_data(Texture *tex);
|
virtual bool extract_texture_data(Texture *tex);
|
||||||
|
|
||||||
|
@ -2637,6 +2637,50 @@ prepare_texture(Texture *tex) {
|
|||||||
return gtc;
|
return gtc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLGraphicsStateGuardian::update_texture
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Ensures that the current Texture data is refreshed
|
||||||
|
// onto the GSG. This means updating the texture
|
||||||
|
// properties and/or re-uploading the texture image, if
|
||||||
|
// necessary. This should only be called within the
|
||||||
|
// draw thread.
|
||||||
|
//
|
||||||
|
// If force is true, this function will not return until
|
||||||
|
// the texture has been fully uploaded. If force is
|
||||||
|
// false, the function may choose to upload a simple
|
||||||
|
// version of the texture instead, if the texture is not
|
||||||
|
// fully resident (and if get_incomplete_render() is
|
||||||
|
// true).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool CLP(GraphicsStateGuardian)::
|
||||||
|
update_texture(TextureContext *tc, bool force) {
|
||||||
|
apply_texture(tc);
|
||||||
|
|
||||||
|
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
||||||
|
|
||||||
|
if (gtc->was_image_modified()) {
|
||||||
|
// If the texture image was modified, reload the texture. This
|
||||||
|
// means we also re-specify the properties for good measure.
|
||||||
|
specify_texture(gtc->get_texture());
|
||||||
|
bool okflag = upload_texture(gtc, force);
|
||||||
|
if (!okflag) {
|
||||||
|
GLCAT.error()
|
||||||
|
<< "Could not load " << *gtc->get_texture() << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (gtc->was_properties_modified()) {
|
||||||
|
// If only the properties have been modified, we don't necessarily
|
||||||
|
// need to reload the texture.
|
||||||
|
specify_texture(gtc->get_texture());
|
||||||
|
gtc->mark_loaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
report_my_gl_errors();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GLGraphicsStateGuardian::release_texture
|
// Function: GLGraphicsStateGuardian::release_texture
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
@ -3275,18 +3319,44 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
|
|||||||
|
|
||||||
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
|
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
|
||||||
nassertr(tc != (TextureContext *)NULL, false);
|
nassertr(tc != (TextureContext *)NULL, false);
|
||||||
apply_texture(tc);
|
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
||||||
|
|
||||||
if (z >= 0) {
|
apply_texture(gtc);
|
||||||
// Copy to a cube map face. This doesn't seem to work too well
|
specify_texture(tex);
|
||||||
// with CopyTexSubImage2D, so we always use CopyTexImage2D.
|
|
||||||
GLP(CopyTexImage2D)(GL_TEXTURE_CUBE_MAP_POSITIVE_X + z, 0,
|
GLenum target = get_texture_target(tex->get_texture_type());
|
||||||
get_internal_image_format(tex),
|
GLint internal_format = get_internal_image_format(tex);
|
||||||
xo, yo, w, h, 0);
|
bool uses_mipmaps = tex->uses_mipmaps() && !CLP(ignore_mipmaps);
|
||||||
} else {
|
if (uses_mipmaps) {
|
||||||
GLP(CopyTexSubImage2D)(GL_TEXTURE_2D, 0, 0, 0, xo, yo, w, h);
|
if (_supports_generate_mipmap) {
|
||||||
|
GLP(TexParameteri)(target, GL_GENERATE_MIPMAP, true);
|
||||||
|
} else {
|
||||||
|
// If we can't auto-generate mipmaps, do without mipmaps.
|
||||||
|
GLP(TexParameteri)(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
uses_mipmaps = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool new_image = gtc->was_image_modified();
|
||||||
|
if (z >= 0) {
|
||||||
|
// Copy to a cube map face.
|
||||||
|
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + z;
|
||||||
|
|
||||||
|
// Cube map faces seem to have trouble with CopyTexSubImage, so we
|
||||||
|
// always reload the image.
|
||||||
|
new_image = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_image) {
|
||||||
|
// We have to create a new image.
|
||||||
|
GLP(CopyTexImage2D)(target, 0, internal_format, xo, yo, w, h, 0);
|
||||||
|
} else {
|
||||||
|
// We can overlay the existing image.
|
||||||
|
GLP(CopyTexSubImage2D)(target, 0, 0, 0, xo, yo, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtc->mark_loaded();
|
||||||
|
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
|
|
||||||
// Force reload of texture state, since we've just monkeyed with it.
|
// Force reload of texture state, since we've just monkeyed with it.
|
||||||
@ -6186,7 +6256,7 @@ update_standard_texture_bindings() {
|
|||||||
}
|
}
|
||||||
GLP(Enable)(target);
|
GLP(Enable)(target);
|
||||||
|
|
||||||
if (!apply_texture(tc)) {
|
if (!update_texture(tc, false)) {
|
||||||
GLP(Disable)(target);
|
GLP(Disable)(target);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -6755,24 +6825,6 @@ apply_texture(TextureContext *tc) {
|
|||||||
}
|
}
|
||||||
GLP(BindTexture)(target, gtc->_index);
|
GLP(BindTexture)(target, gtc->_index);
|
||||||
|
|
||||||
if (gtc->was_image_modified()) {
|
|
||||||
// If the texture image was modified, reload the texture. This
|
|
||||||
// means we also re-specify the properties for good measure.
|
|
||||||
specify_texture(gtc->get_texture());
|
|
||||||
bool okflag = upload_texture(gtc);
|
|
||||||
if (!okflag) {
|
|
||||||
GLCAT.error()
|
|
||||||
<< "Could not load " << *gtc->get_texture() << "\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (gtc->was_properties_modified()) {
|
|
||||||
// If only the properties have been modified, we don't necessarily
|
|
||||||
// need to reload the texture.
|
|
||||||
specify_texture(gtc->get_texture());
|
|
||||||
gtc->mark_loaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -6787,10 +6839,10 @@ apply_texture(TextureContext *tc) {
|
|||||||
// the texture has no image.
|
// the texture has no image.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool CLP(GraphicsStateGuardian)::
|
bool CLP(GraphicsStateGuardian)::
|
||||||
upload_texture(CLP(TextureContext) *gtc) {
|
upload_texture(CLP(TextureContext) *gtc, bool force) {
|
||||||
Texture *tex = gtc->get_texture();
|
Texture *tex = gtc->get_texture();
|
||||||
|
|
||||||
if (_incomplete_render) {
|
if (_incomplete_render && !force) {
|
||||||
bool has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
|
bool has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
|
||||||
if (!has_image && tex->might_have_ram_image() &&
|
if (!has_image && tex->might_have_ram_image() &&
|
||||||
tex->has_simple_ram_image() &&
|
tex->has_simple_ram_image() &&
|
||||||
@ -6827,6 +6879,13 @@ upload_texture(CLP(TextureContext) *gtc) {
|
|||||||
image_compression = Texture::CM_off;
|
image_compression = Texture::CM_off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (image.is_null()) {
|
||||||
|
// If we don't have an image, we can't upload.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
int mipmap_bias = 0;
|
int mipmap_bias = 0;
|
||||||
|
|
||||||
int width = tex->get_x_size();
|
int width = tex->get_x_size();
|
||||||
|
@ -143,6 +143,7 @@ public:
|
|||||||
INLINE bool draw_display_list(GeomContext *gc);
|
INLINE bool draw_display_list(GeomContext *gc);
|
||||||
|
|
||||||
virtual TextureContext *prepare_texture(Texture *tex);
|
virtual TextureContext *prepare_texture(Texture *tex);
|
||||||
|
virtual bool update_texture(TextureContext *tc, bool force);
|
||||||
virtual void release_texture(TextureContext *tc);
|
virtual void release_texture(TextureContext *tc);
|
||||||
virtual bool extract_texture_data(Texture *tex);
|
virtual bool extract_texture_data(Texture *tex);
|
||||||
|
|
||||||
@ -324,7 +325,7 @@ protected:
|
|||||||
void do_auto_rescale_normal();
|
void do_auto_rescale_normal();
|
||||||
void specify_texture(Texture *tex);
|
void specify_texture(Texture *tex);
|
||||||
bool apply_texture(TextureContext *tc);
|
bool apply_texture(TextureContext *tc);
|
||||||
bool upload_texture(CLP(TextureContext) *gtc);
|
bool upload_texture(CLP(TextureContext) *gtc, bool force);
|
||||||
bool upload_texture_image(CLP(TextureContext) *gtc,
|
bool upload_texture_image(CLP(TextureContext) *gtc,
|
||||||
bool uses_mipmaps, int mipmap_bias,
|
bool uses_mipmaps, int mipmap_bias,
|
||||||
GLenum texture_target, GLenum page_target,
|
GLenum texture_target, GLenum page_target,
|
||||||
|
@ -1214,7 +1214,8 @@ begin_frame(GraphicsStateGuardianBase *gsg, Thread *current_thread) {
|
|||||||
qti != _enqueued_textures.end();
|
qti != _enqueued_textures.end();
|
||||||
++qti) {
|
++qti) {
|
||||||
Texture *tex = (*qti);
|
Texture *tex = (*qti);
|
||||||
tex->prepare_now(this, gsg);
|
TextureContext *tc = tex->prepare_now(this, gsg);
|
||||||
|
gsg->update_texture(tc, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_enqueued_textures.clear();
|
_enqueued_textures.clear();
|
||||||
|
@ -133,6 +133,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual TextureContext *prepare_texture(Texture *tex)=0;
|
virtual TextureContext *prepare_texture(Texture *tex)=0;
|
||||||
|
virtual bool update_texture(TextureContext *tc, bool force)=0;
|
||||||
virtual void release_texture(TextureContext *tc)=0;
|
virtual void release_texture(TextureContext *tc)=0;
|
||||||
virtual bool extract_texture_data(Texture *tex)=0;
|
virtual bool extract_texture_data(Texture *tex)=0;
|
||||||
|
|
||||||
|
@ -352,6 +352,35 @@ safe_to_combine() const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomNode::r_prepare_scene
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: The recursive implementation of prepare_scene().
|
||||||
|
// Don't call this directly; call
|
||||||
|
// PandaNode::prepare_scene() or
|
||||||
|
// NodePath::prepare_scene() instead.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void GeomNode::
|
||||||
|
r_prepare_scene(const RenderState *state,
|
||||||
|
PreparedGraphicsObjects *prepared_objects) {
|
||||||
|
int num_geoms = get_num_geoms();
|
||||||
|
for (int i = 0; i < num_geoms; i++) {
|
||||||
|
CPT(RenderState) geom_state = state->compose(get_geom_state(i));
|
||||||
|
const RenderAttrib *attrib =
|
||||||
|
geom_state->get_attrib(TextureAttrib::get_class_type());
|
||||||
|
if (attrib != (const RenderAttrib *)NULL) {
|
||||||
|
const TextureAttrib *ta;
|
||||||
|
DCAST_INTO_V(ta, attrib);
|
||||||
|
Texture *texture = ta->get_texture();
|
||||||
|
if (texture != (Texture *)NULL) {
|
||||||
|
texture->prepare(prepared_objects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PandaNode::r_prepare_scene(state, prepared_objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GeomNode::combine_with
|
// Function: GeomNode::combine_with
|
||||||
|
@ -59,6 +59,9 @@ public:
|
|||||||
virtual bool safe_to_flatten() const;
|
virtual bool safe_to_flatten() const;
|
||||||
virtual bool safe_to_combine() const;
|
virtual bool safe_to_combine() const;
|
||||||
|
|
||||||
|
virtual void r_prepare_scene(const RenderState *state,
|
||||||
|
PreparedGraphicsObjects *prepared_objects);
|
||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
INLINE void set_preserved(bool value);
|
INLINE void set_preserved(bool value);
|
||||||
INLINE bool get_preserved() const;
|
INLINE bool get_preserved() const;
|
||||||
|
@ -5752,10 +5752,8 @@ void NodePath::
|
|||||||
prepare_scene(GraphicsStateGuardianBase *gsg) {
|
prepare_scene(GraphicsStateGuardianBase *gsg) {
|
||||||
nassertv_always(!is_empty());
|
nassertv_always(!is_empty());
|
||||||
|
|
||||||
PreparedGraphicsObjects *prepared_objects = gsg->get_prepared_objects();
|
|
||||||
|
|
||||||
CPT(RenderState) net_state = get_net_state();
|
CPT(RenderState) net_state = get_net_state();
|
||||||
r_prepare_scene(node(), net_state, prepared_objects);
|
node()->prepare_scene(gsg, net_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -7009,46 +7007,3 @@ r_find_all_materials(PandaNode *node, const RenderState *state,
|
|||||||
r_find_all_materials(child, next_state, materials);
|
r_find_all_materials(child, next_state, materials);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: NodePath::r_prepare_scene
|
|
||||||
// Access: Private
|
|
||||||
// Description: The recursive implementation of prepare_scene.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void NodePath::
|
|
||||||
r_prepare_scene(PandaNode *node, const RenderState *state,
|
|
||||||
PreparedGraphicsObjects *prepared_objects) {
|
|
||||||
if (node->is_geom_node()) {
|
|
||||||
GeomNode *gnode;
|
|
||||||
DCAST_INTO_V(gnode, node);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Not implemented yet in pgraph. Maybe we don't need this anyway.
|
|
||||||
if (retained_mode) {
|
|
||||||
gnode->prepare(gsg);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
int num_geoms = gnode->get_num_geoms();
|
|
||||||
for (int i = 0; i < num_geoms; i++) {
|
|
||||||
CPT(RenderState) geom_state = state->compose(gnode->get_geom_state(i));
|
|
||||||
const RenderAttrib *attrib =
|
|
||||||
geom_state->get_attrib(TextureAttrib::get_class_type());
|
|
||||||
if (attrib != (const RenderAttrib *)NULL) {
|
|
||||||
const TextureAttrib *ta;
|
|
||||||
DCAST_INTO_V(ta, attrib);
|
|
||||||
Texture *texture = ta->get_texture();
|
|
||||||
if (texture != (Texture *)NULL) {
|
|
||||||
texture->prepare(prepared_objects);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int num_children = node->get_num_children();
|
|
||||||
for (int i = 0; i < num_children; i++) {
|
|
||||||
PandaNode *child = node->get_child(i);
|
|
||||||
CPT(RenderState) child_state = state->compose(child->get_state());
|
|
||||||
r_prepare_scene(child, child_state, prepared_objects);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -913,9 +913,6 @@ private:
|
|||||||
void r_find_all_materials(PandaNode *node, const RenderState *state,
|
void r_find_all_materials(PandaNode *node, const RenderState *state,
|
||||||
Materials &materials) const;
|
Materials &materials) const;
|
||||||
|
|
||||||
void r_prepare_scene(PandaNode *node, const RenderState *state,
|
|
||||||
PreparedGraphicsObjects *prepared_objects);
|
|
||||||
|
|
||||||
PT(NodePathComponent) _head;
|
PT(NodePathComponent) _head;
|
||||||
int _backup_key;
|
int _backup_key;
|
||||||
ErrorType _error_type;
|
ErrorType _error_type;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "pStatTimer.h"
|
#include "pStatTimer.h"
|
||||||
#include "config_mathutil.h"
|
#include "config_mathutil.h"
|
||||||
#include "reMutexHolder.h"
|
#include "reMutexHolder.h"
|
||||||
|
#include "graphicsStateGuardianBase.h"
|
||||||
|
|
||||||
// This category is just temporary for debugging convenience.
|
// This category is just temporary for debugging convenience.
|
||||||
NotifyCategoryDecl(drawmask, EXPCL_PANDA_PGRAPH, EXPTP_PANDA_PGRAPH);
|
NotifyCategoryDecl(drawmask, EXPCL_PANDA_PGRAPH, EXPTP_PANDA_PGRAPH);
|
||||||
@ -2105,6 +2106,27 @@ get_off_clip_planes(Thread *current_thread) const {
|
|||||||
return cdata->_off_clip_planes;
|
return cdata->_off_clip_planes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PandaNode::prepare_scene
|
||||||
|
// Access: Published
|
||||||
|
// Description: Walks through the scene graph beginning at this node,
|
||||||
|
// and does whatever initialization is required to
|
||||||
|
// render the scene properly with the indicated GSG. It
|
||||||
|
// is not strictly necessary to call this, since the GSG
|
||||||
|
// will initialize itself when the scene is rendered,
|
||||||
|
// but this may take some of the overhead away from that
|
||||||
|
// process.
|
||||||
|
//
|
||||||
|
// In particular, this will ensure that textures within
|
||||||
|
// the scene are loaded in texture memory, and display
|
||||||
|
// lists are built up from static geometry.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PandaNode::
|
||||||
|
prepare_scene(GraphicsStateGuardianBase *gsg, const RenderState *net_state) {
|
||||||
|
PreparedGraphicsObjects *prepared_objects = gsg->get_prepared_objects();
|
||||||
|
r_prepare_scene(net_state, prepared_objects);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaNode::output
|
// Function: PandaNode::output
|
||||||
// Access: Published, Virtual
|
// Access: Published, Virtual
|
||||||
@ -2661,6 +2683,25 @@ r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PandaNode::r_prepare_scene
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: The recursive implementation of prepare_scene().
|
||||||
|
// Don't call this directly; call
|
||||||
|
// PandaNode::prepare_scene() or
|
||||||
|
// NodePath::prepare_scene() instead.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PandaNode::
|
||||||
|
r_prepare_scene(const RenderState *state,
|
||||||
|
PreparedGraphicsObjects *prepared_objects) {
|
||||||
|
int num_children = get_num_children();
|
||||||
|
for (int i = 0; i < num_children; i++) {
|
||||||
|
PandaNode *child = get_child(i);
|
||||||
|
CPT(RenderState) child_state = state->compose(child->get_state());
|
||||||
|
child->r_prepare_scene(child_state, prepared_objects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PandaNode::set_cull_callback
|
// Function: PandaNode::set_cull_callback
|
||||||
// Access: Protected
|
// Access: Protected
|
||||||
|
@ -60,6 +60,7 @@ class Light;
|
|||||||
class FactoryParams;
|
class FactoryParams;
|
||||||
class AccumulatedAttribs;
|
class AccumulatedAttribs;
|
||||||
class GeomTransformer;
|
class GeomTransformer;
|
||||||
|
class GraphicsStateGuardianBase;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : PandaNode
|
// Class : PandaNode
|
||||||
@ -239,6 +240,8 @@ PUBLISHED:
|
|||||||
CollideMask get_net_collide_mask(Thread *current_thread = Thread::get_current_thread()) const;
|
CollideMask get_net_collide_mask(Thread *current_thread = Thread::get_current_thread()) const;
|
||||||
CPT(RenderAttrib) get_off_clip_planes(Thread *current_thread = Thread::get_current_thread()) const;
|
CPT(RenderAttrib) get_off_clip_planes(Thread *current_thread = Thread::get_current_thread()) const;
|
||||||
|
|
||||||
|
void prepare_scene(GraphicsStateGuardianBase *gsg, const RenderState *net_state);
|
||||||
|
|
||||||
virtual void output(ostream &out) const;
|
virtual void output(ostream &out) const;
|
||||||
virtual void write(ostream &out, int indent_level) const;
|
virtual void write(ostream &out, int indent_level) const;
|
||||||
|
|
||||||
@ -314,6 +317,10 @@ protected:
|
|||||||
|
|
||||||
void set_cull_callback();
|
void set_cull_callback();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void r_prepare_scene(const RenderState *state,
|
||||||
|
PreparedGraphicsObjects *prepared_objects);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// This is a base class of CData, defined below. It contains just
|
// This is a base class of CData, defined below. It contains just
|
||||||
// the protected (not private) part of CData that will be needed by
|
// the protected (not private) part of CData that will be needed by
|
||||||
|
@ -335,6 +335,30 @@ compute_internal_bounds(PandaNode::BoundsData *bdata, int pipeline_stage,
|
|||||||
bdata->_internal_bounds_stale = false;
|
bdata->_internal_bounds_stale = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PGItem::r_prepare_scene
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: The recursive implementation of prepare_scene().
|
||||||
|
// Don't call this directly; call
|
||||||
|
// PandaNode::prepare_scene() or
|
||||||
|
// NodePath::prepare_scene() instead.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PGItem::
|
||||||
|
r_prepare_scene(const RenderState *state,
|
||||||
|
PreparedGraphicsObjects *prepared_objects) {
|
||||||
|
StateDefs::iterator di;
|
||||||
|
for (di = _state_defs.begin(); di != _state_defs.end(); ++di) {
|
||||||
|
NodePath &root = (*di)._root;
|
||||||
|
if (!root.is_empty()) {
|
||||||
|
PandaNode *child = root.node();
|
||||||
|
CPT(RenderState) child_state = state->compose(child->get_state());
|
||||||
|
child->r_prepare_scene(child_state, prepared_objects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PandaNode::r_prepare_scene(state, prepared_objects);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PGItem::xform
|
// Function: PGItem::xform
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -68,6 +68,9 @@ protected:
|
|||||||
virtual void compute_internal_bounds(BoundsData *bdata, int pipeline_stage,
|
virtual void compute_internal_bounds(BoundsData *bdata, int pipeline_stage,
|
||||||
Thread *current_thread) const;
|
Thread *current_thread) const;
|
||||||
|
|
||||||
|
virtual void r_prepare_scene(const RenderState *state,
|
||||||
|
PreparedGraphicsObjects *prepared_objects);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void xform(const LMatrix4f &mat);
|
virtual void xform(const LMatrix4f &mat);
|
||||||
bool activate_region(const LMatrix4f &transform, int sort,
|
bool activate_region(const LMatrix4f &transform, int sort,
|
||||||
|
@ -649,6 +649,28 @@ compute_internal_bounds(PandaNode::BoundsData *bdata, int pipeline_stage,
|
|||||||
bdata->_internal_bounds_stale = false;
|
bdata->_internal_bounds_stale = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TextNode::r_prepare_scene
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: The recursive implementation of prepare_scene().
|
||||||
|
// Don't call this directly; call
|
||||||
|
// PandaNode::prepare_scene() or
|
||||||
|
// NodePath::prepare_scene() instead.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void TextNode::
|
||||||
|
r_prepare_scene(const RenderState *state,
|
||||||
|
PreparedGraphicsObjects *prepared_objects) {
|
||||||
|
check_rebuild();
|
||||||
|
|
||||||
|
PandaNode *child = _internal_geom;
|
||||||
|
if (child != (PandaNode *)NULL) {
|
||||||
|
CPT(RenderState) child_state = state->compose(child->get_state());
|
||||||
|
child->r_prepare_scene(child_state, prepared_objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
PandaNode::r_prepare_scene(state, prepared_objects);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TextNode::do_rebuild
|
// Function: TextNode::do_rebuild
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -242,6 +242,9 @@ public:
|
|||||||
virtual void compute_internal_bounds(BoundsData *bdata, int pipeline_stage,
|
virtual void compute_internal_bounds(BoundsData *bdata, int pipeline_stage,
|
||||||
Thread *current_thread) const;
|
Thread *current_thread) const;
|
||||||
|
|
||||||
|
virtual void r_prepare_scene(const RenderState *state,
|
||||||
|
PreparedGraphicsObjects *prepared_objects);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
INLINE void invalidate_no_measure();
|
INLINE void invalidate_no_measure();
|
||||||
INLINE void invalidate_with_measure();
|
INLINE void invalidate_with_measure();
|
||||||
|
@ -1468,6 +1468,47 @@ prepare_texture(Texture *tex) {
|
|||||||
return gtc;
|
return gtc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: TinyGraphicsStateGuardian::update_texture
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Ensures that the current Texture data is refreshed
|
||||||
|
// onto the GSG. This means updating the texture
|
||||||
|
// properties and/or re-uploading the texture image, if
|
||||||
|
// necessary. This should only be called within the
|
||||||
|
// draw thread.
|
||||||
|
//
|
||||||
|
// If force is true, this function will not return until
|
||||||
|
// the texture has been fully uploaded. If force is
|
||||||
|
// false, the function may choose to upload a simple
|
||||||
|
// version of the texture instead, if the texture is not
|
||||||
|
// fully resident (and if get_incomplete_render() is
|
||||||
|
// true).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool TinyGraphicsStateGuardian::
|
||||||
|
update_texture(TextureContext *tc, bool force) {
|
||||||
|
apply_texture(tc);
|
||||||
|
|
||||||
|
TinyTextureContext *gtc = DCAST(TinyTextureContext, tc);
|
||||||
|
|
||||||
|
GLTexture *gltex = >c->_gltex;
|
||||||
|
|
||||||
|
if (gtc->was_image_modified() || gltex->num_levels == 0) {
|
||||||
|
// If the texture image was modified, reload the texture.
|
||||||
|
bool okflag = upload_texture(gtc);
|
||||||
|
if (!okflag) {
|
||||||
|
tinydisplay_cat.error()
|
||||||
|
<< "Could not load " << *gtc->get_texture() << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gtc->enqueue_lru(&_textures_lru);
|
||||||
|
|
||||||
|
_c->current_texture = gltex;
|
||||||
|
_c->zb->current_texture = gltex->levels;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: TinyGraphicsStateGuardian::release_texture
|
// Function: TinyGraphicsStateGuardian::release_texture
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
@ -1874,7 +1915,7 @@ do_issue_texture() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Then, turn on the current texture mode.
|
// Then, turn on the current texture mode.
|
||||||
if (!apply_texture(tc)) {
|
if (!update_texture(tc, false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1981,22 +2022,6 @@ apply_texture(TextureContext *tc) {
|
|||||||
TinyTextureContext *gtc = DCAST(TinyTextureContext, tc);
|
TinyTextureContext *gtc = DCAST(TinyTextureContext, tc);
|
||||||
|
|
||||||
gtc->set_active(true);
|
gtc->set_active(true);
|
||||||
|
|
||||||
GLTexture *gltex = >c->_gltex;
|
|
||||||
|
|
||||||
if (gtc->was_image_modified() || gltex->num_levels == 0) {
|
|
||||||
// If the texture image was modified, reload the texture.
|
|
||||||
bool okflag = upload_texture(gtc);
|
|
||||||
if (!okflag) {
|
|
||||||
tinydisplay_cat.error()
|
|
||||||
<< "Could not load " << *gtc->get_texture() << "\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gtc->enqueue_lru(&_textures_lru);
|
|
||||||
|
|
||||||
_c->current_texture = gltex;
|
|
||||||
_c->zb->current_texture = gltex->levels;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +85,7 @@ public:
|
|||||||
const TransformState *transform);
|
const TransformState *transform);
|
||||||
|
|
||||||
virtual TextureContext *prepare_texture(Texture *tex);
|
virtual TextureContext *prepare_texture(Texture *tex);
|
||||||
|
virtual bool update_texture(TextureContext *tc, bool force);
|
||||||
virtual void release_texture(TextureContext *tc);
|
virtual void release_texture(TextureContext *tc);
|
||||||
|
|
||||||
virtual void do_issue_light();
|
virtual void do_issue_light();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user