From 67e3f1daa6ee3d5c47f2f32f8fc126f2f0356773 Mon Sep 17 00:00:00 2001 From: David Rose Date: Sat, 23 Jul 2005 18:03:10 +0000 Subject: [PATCH] expose Texture::T_depth_component, sanify a few things --- panda/src/display/graphicsStateGuardian.cxx | 15 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 199 +++++++++++------- panda/src/gobj/texture.I | 24 +-- panda/src/gobj/texture.cxx | 5 +- panda/src/gobj/texture.h | 6 +- panda/src/grutil/cardMaker.I | 16 ++ panda/src/grutil/cardMaker.cxx | 24 ++- panda/src/grutil/cardMaker.h | 4 + panda/src/pgraph/lensNode.cxx | 4 +- panda/src/pgraph/nodePath.cxx | 17 +- panda/src/pnmimage/pnmImage.cxx | 4 +- 11 files changed, 197 insertions(+), 121 deletions(-) diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 5ae03bbfc0..5dee2ef839 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -641,13 +641,16 @@ begin_frame() { // For Pstats to track our current texture memory usage, we have to // reset the set of current textures each frame. init_frame_pstats(); - - // But since we don't get sent a new issue_texture() unless our - // texture state has changed, we have to be sure to clear the - // current texture state now. A bit unfortunate, but probably not - // measurably expensive. - modify_state(get_untextured_state()); #endif + + // We should reset the state to the default at the beginning of + // every frame. Although this will incur additional overhead, + // particularly in a simple scene, it helps ensure that states that + // have changed properties since last time without changing + // attribute pointers--like textures, lighting, or fog--will still + // be accurately updated. + set_state(RenderState::make_empty()); + return true; } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 18ed3471b0..344be6bf50 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -880,22 +880,22 @@ do_clear(const RenderBuffer &buffer) { mask |= GL_ACCUM_BUFFER_BIT; } -#ifdef GSG_VERBOSE - GLCAT.spam() << "glClear("; - if (mask & GL_COLOR_BUFFER_BIT) { - GLCAT.spam(false) << "GL_COLOR_BUFFER_BIT|"; + if (GLCAT.is_spam()) { + GLCAT.spam() << "glClear("; + if (mask & GL_COLOR_BUFFER_BIT) { + GLCAT.spam(false) << "GL_COLOR_BUFFER_BIT|"; + } + if (mask & GL_DEPTH_BUFFER_BIT) { + GLCAT.spam(false) << "GL_DEPTH_BUFFER_BIT|"; + } + if (mask & GL_STENCIL_BUFFER_BIT) { + GLCAT.spam(false) << "GL_STENCIL_BUFFER_BIT|"; + } + if (mask & GL_ACCUM_BUFFER_BIT) { + GLCAT.spam(false) << "GL_ACCUM_BUFFER_BIT|"; + } + GLCAT.spam(false) << ")" << endl; } - if (mask & GL_DEPTH_BUFFER_BIT) { - GLCAT.spam(false) << "GL_DEPTH_BUFFER_BIT|"; - } - if (mask & GL_STENCIL_BUFFER_BIT) { - GLCAT.spam(false) << "GL_STENCIL_BUFFER_BIT|"; - } - if (mask & GL_ACCUM_BUFFER_BIT) { - GLCAT.spam(false) << "GL_ACCUM_BUFFER_BIT|"; - } - GLCAT.spam(false) << ")" << endl; -#endif modify_state(state); @@ -981,10 +981,10 @@ prepare_lens() { _projection_mat *= invert_mat; } -#ifdef GSG_VERBOSE - GLCAT.spam() - << "glMatrixMode(GL_PROJECTION): " << _projection_mat << endl; -#endif + if (GLCAT.is_spam()) { + GLCAT.spam() + << "glMatrixMode(GL_PROJECTION): " << _projection_mat << endl; + } GLP(MatrixMode)(GL_PROJECTION); GLP(LoadMatrixf)(_projection_mat.get_data()); report_my_gl_errors(); @@ -2135,12 +2135,22 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, tex->set_y_size(h); if (tex->get_match_framebuffer_format()) { - FrameBufferProperties properties = get_properties(); + const FrameBufferProperties &properties = get_properties(); int mode = properties.get_frame_buffer_mode(); - if (mode & FrameBufferProperties::FM_alpha) { - tex->set_format(Texture::F_rgba); - } else { - tex->set_format(Texture::F_rgb); + + switch (tex->get_format()) { + case Texture::F_depth_component: + case Texture::F_stencil_index: + // If the texture is one of these special formats, we don't want + // to adapt it to the framebuffer's color format. + break; + + default: + if (mode & FrameBufferProperties::FM_alpha) { + tex->set_format(Texture::F_rgba); + } else { + tex->set_format(Texture::F_rgb); + } } } @@ -2210,19 +2220,41 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, dr->get_region_pixels(xo, yo, w, h); const FrameBufferProperties &properties = get_properties(); + int mode = properties.get_frame_buffer_mode(); - Texture::ComponentType component_type; - if (properties.get_color_bits() <= 24) { - component_type = Texture::T_unsigned_byte; - } else { - component_type = Texture::T_unsigned_short; - } + Texture::Format format = tex->get_format(); + Texture::ComponentType component_type = tex->get_component_type(); + bool color_mode = false; - Texture::Format format; - if (properties.get_frame_buffer_mode() & FrameBufferProperties::FM_alpha) { - format = Texture::F_rgba; - } else { - format = Texture::F_rgb; + switch (format) { + case Texture::F_depth_component: + if (properties.get_depth_bits() <= 8) { + component_type = Texture::T_unsigned_byte; + } else { + component_type = Texture::T_unsigned_short; + } + break; + + case Texture::F_stencil_index: + if (properties.get_stencil_bits() <= 8) { + component_type = Texture::T_unsigned_byte; + } else { + component_type = Texture::T_unsigned_short; + } + break; + + default: + color_mode = true; + if (mode & FrameBufferProperties::FM_alpha) { + format = Texture::F_rgba; + } else { + format = Texture::F_rgb; + } + if (properties.get_color_bits() <= 24) { + component_type = Texture::T_unsigned_byte; + } else { + component_type = Texture::T_unsigned_short; + } } Texture::TextureType texture_type; @@ -2243,46 +2275,46 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, GLenum external_format = get_external_image_format(format); -#ifdef GSG_VERBOSE - GLCAT.debug() - << "glReadPixels(" << xo << ", " << yo << ", " << w << ", " << h << ", "; - switch (external_format) { - case GL_DEPTH_COMPONENT: - GLCAT.debug(false) << "GL_DEPTH_COMPONENT, "; - break; - case GL_RGB: - GLCAT.debug(false) << "GL_RGB, "; - break; - case GL_RGBA: - GLCAT.debug(false) << "GL_RGBA, "; - break; - case GL_BGR: - GLCAT.debug(false) << "GL_BGR, "; - break; - case GL_BGRA: - GLCAT.debug(false) << "GL_BGRA, "; - break; - default: - GLCAT.debug(false) << "unknown, "; - break; + if (GLCAT.is_spam()) { + GLCAT.spam() + << "glReadPixels(" << xo << ", " << yo << ", " << w << ", " << h << ", "; + switch (external_format) { + case GL_DEPTH_COMPONENT: + GLCAT.spam(false) << "GL_DEPTH_COMPONENT, "; + break; + case GL_RGB: + GLCAT.spam(false) << "GL_RGB, "; + break; + case GL_RGBA: + GLCAT.spam(false) << "GL_RGBA, "; + break; + case GL_BGR: + GLCAT.spam(false) << "GL_BGR, "; + break; + case GL_BGRA: + GLCAT.spam(false) << "GL_BGRA, "; + break; + default: + GLCAT.spam(false) << "unknown, "; + break; + } + switch (get_component_type(component_type)) { + case GL_UNSIGNED_BYTE: + GLCAT.spam(false) << "GL_UNSIGNED_BYTE, "; + break; + case GL_UNSIGNED_SHORT: + GLCAT.spam(false) << "GL_UNSIGNED_SHORT, "; + break; + case GL_FLOAT: + GLCAT.spam(false) << "GL_FLOAT, "; + break; + default: + GLCAT.spam(false) << "unknown, "; + break; + } + GLCAT.spam(false) + << ")" << endl; } - switch (get_component_type(component_type)) { - case GL_UNSIGNED_BYTE: - GLCAT.debug(false) << "GL_UNSIGNED_BYTE, "; - break; - case GL_UNSIGNED_SHORT: - GLCAT.debug(false) << "GL_UNSIGNED_SHORT, "; - break; - case GL_FLOAT: - GLCAT.debug(false) << "GL_FLOAT, "; - break; - default: - GLCAT.debug(false) << "unknown, "; - break; - } - GLCAT.debug(false) - << ")" << endl; -#endif unsigned char *image = tex->modify_ram_image(); if (z >= 0) { @@ -2298,7 +2330,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, // didn't do it for us. This assumes we render out the six faces of // a cube map in ascending order, since we can't do this until we // have rendered the last face. - if (!_supports_bgr && (z == -1 || z == 5)) { + if (color_mode && !_supports_bgr && (z == -1 || z == 5)) { tex->set_ram_image(fix_component_ordering(tex->get_ram_image(), external_format, tex)); } @@ -2343,10 +2375,11 @@ apply_fog(Fog *fog) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: issue_transform(const TransformState *transform) { -#ifdef GSG_VERBOSE - GLCAT.spam() - << "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl; -#endif + if (GLCAT.is_spam()) { + GLCAT.spam() + << "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl; + } + DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1)); GLP(MatrixMode)(GL_MODELVIEW); GLP(LoadMatrixf)(transform->get_mat().get_data()); @@ -3401,6 +3434,7 @@ get_external_image_format(Texture::Format format) const { return GL_STENCIL_INDEX; case Texture::F_depth_component: return GL_DEPTH_COMPONENT; + case Texture::F_red: return GL_RED; case Texture::F_green: @@ -3443,6 +3477,13 @@ get_external_image_format(Texture::Format format) const { GLint CLP(GraphicsStateGuardian):: get_internal_image_format(Texture::Format format) { switch (format) { + case Texture::F_color_index: + return GL_COLOR_INDEX; + case Texture::F_stencil_index: + return GL_STENCIL_INDEX; + case Texture::F_depth_component: + return GL_DEPTH_COMPONENT; + case Texture::F_rgba: case Texture::F_rgbm: return GL_RGBA; diff --git a/panda/src/gobj/texture.I b/panda/src/gobj/texture.I index 00f6abcc16..15e45e0489 100644 --- a/panda/src/gobj/texture.I +++ b/panda/src/gobj/texture.I @@ -529,7 +529,7 @@ get_keep_ram_image() const { //////////////////////////////////////////////////////////////////// // Function: Texture::set_filename -// Access: Public +// Access: Published // Description: Sets the name of the file that contains the image's // contents. Normally, this is set automatically when // the image is loaded, for instance via @@ -547,7 +547,7 @@ set_filename(const Filename &filename) { //////////////////////////////////////////////////////////////////// // Function: Texture::clear_filename -// Access: Public +// Access: Published // Description: Removes the alpha filename, if it was previously set. // See set_filename(). //////////////////////////////////////////////////////////////////// @@ -558,7 +558,7 @@ clear_filename() { //////////////////////////////////////////////////////////////////// // Function: Texture::set_alpha_filename -// Access: Public +// Access: Published // Description: Sets the name of the file that contains the image's // alpha channel contents. Normally, this is set // automatically when the image is loaded, for instance @@ -579,7 +579,7 @@ set_alpha_filename(const Filename &alpha_filename) { //////////////////////////////////////////////////////////////////// // Function: Texture::clear_alpha_filename -// Access: Public +// Access: Published // Description: Removes the alpha filename, if it was previously set. // See set_alpha_filename(). //////////////////////////////////////////////////////////////////// @@ -590,7 +590,7 @@ clear_alpha_filename() { //////////////////////////////////////////////////////////////////// // Function: Texture::set_fullpath -// Access: Public +// Access: Published // Description: Sets the full pathname to the file that contains the // image's contents, as found along the search path. // Normally, this is set automatically when the image is @@ -603,7 +603,7 @@ set_fullpath(const Filename &fullpath) { //////////////////////////////////////////////////////////////////// // Function: Texture::clear_fullpath -// Access: Public +// Access: Published // Description: Removes the alpha fullpath, if it was previously set. // See set_fullpath(). //////////////////////////////////////////////////////////////////// @@ -614,7 +614,7 @@ clear_fullpath() { //////////////////////////////////////////////////////////////////// // Function: Texture::set_alpha_fullpath -// Access: Public +// Access: Published // Description: Sets the full pathname to the file that contains the // image's alpha channel contents, as found along the // search path. Normally, this is set automatically @@ -628,7 +628,7 @@ set_alpha_fullpath(const Filename &alpha_fullpath) { //////////////////////////////////////////////////////////////////// // Function: Texture::clear_alpha_fullpath -// Access: Public +// Access: Published // Description: Removes the alpha fullpath, if it was previously set. // See set_alpha_fullpath(). //////////////////////////////////////////////////////////////////// @@ -639,7 +639,7 @@ clear_alpha_fullpath() { //////////////////////////////////////////////////////////////////// // Function: Texture::set_x_size -// Access: Public +// Access: Published // Description: Changes the x size indicated for the texture. This // also implicitly unloads the texture if it has already // been loaded. @@ -654,7 +654,7 @@ set_x_size(int x_size) { //////////////////////////////////////////////////////////////////// // Function: Texture::set_y_size -// Access: Public +// Access: Published // Description: Changes the y size indicated for the texture. This // also implicitly unloads the texture if it has already // been loaded. @@ -670,7 +670,7 @@ set_y_size(int y_size) { //////////////////////////////////////////////////////////////////// // Function: Texture::set_z_size -// Access: Public +// Access: Published // Description: Changes the z size indicated for the texture. This // also implicitly unloads the texture if it has already // been loaded. @@ -688,7 +688,7 @@ set_z_size(int z_size) { //////////////////////////////////////////////////////////////////// // Function: Texture::set_loaded_from_disk -// Access: Public +// Access: Published // Description: Sets the flag that indicates the texture has been // loaded from a disk file. You should also ensure the // filename has been set correctly. When this flag is diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index 4857f82967..388a565620 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -720,6 +720,7 @@ load(const PNMImage &pnmimage, int z) { //////////////////////////////////////////////////////////////////// bool Texture:: store(PNMImage &pnmimage, int z) const { + nassertr(has_ram_image(), false); nassertr(z >= 0 && z < _z_size, false); if (_component_type == T_unsigned_byte) { @@ -1070,7 +1071,7 @@ release_all() { //////////////////////////////////////////////////////////////////// // Function: Texture::set_format -// Access: Public +// Access: Published // Description: Changes the format value for the texture components. // This implicitly sets num_components as well. //////////////////////////////////////////////////////////////////// @@ -1116,7 +1117,7 @@ set_format(Texture::Format format) { //////////////////////////////////////////////////////////////////// // Function: Texture::set_component_type -// Access: Public +// Access: Published // Description: Changes the data value for the texture components. // This implicitly sets component_width as well. //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/texture.h b/panda/src/gobj/texture.h index 521e4642ae..a3a2b39580 100644 --- a/panda/src/gobj/texture.h +++ b/panda/src/gobj/texture.h @@ -218,9 +218,9 @@ PUBLISHED: bool release(PreparedGraphicsObjects *prepared_objects); int release_all(); -public: - // These are public, but in general, you shouldn't be mucking with - // these values; they are set automatically when a texture is +PUBLISHED: + // These are published, but in general, you shouldn't be mucking + // with these values; they are set automatically when a texture is // loaded. INLINE void set_filename(const Filename &filename); INLINE void clear_filename(); diff --git a/panda/src/grutil/cardMaker.I b/panda/src/grutil/cardMaker.I index 0df1ccdb6b..65b3278c84 100644 --- a/panda/src/grutil/cardMaker.I +++ b/panda/src/grutil/cardMaker.I @@ -103,6 +103,22 @@ set_color(const LVecBase4f &color) { _has_color = true; } +//////////////////////////////////////////////////////////////////// +// Function: CardMaker::set_has_normals +// Access: Public +// Description: Sets the flag indicating whether vertices will be +// generated with normals or not. Normals are required +// if you intend to enable lighting on the card, but are +// just wasted space and bandwidth otherwise, so there +// is a (slight) optimization for disabling them. If +// enabled, the normals will be generated perpendicular +// to the card's face. +//////////////////////////////////////////////////////////////////// +INLINE void CardMaker:: +set_has_normals(bool flag) { + _has_normals = flag; +} + //////////////////////////////////////////////////////////////////// // Function: CardMaker::set_source_geometry // Access: Published diff --git a/panda/src/grutil/cardMaker.cxx b/panda/src/grutil/cardMaker.cxx index 6cd8a2c74d..588fd8e9fc 100644 --- a/panda/src/grutil/cardMaker.cxx +++ b/panda/src/grutil/cardMaker.cxx @@ -39,6 +39,7 @@ reset() { _frame.set(0.0f, 1.0f, 0.0f, 1.0f); _has_color = false; _color.set(1.0f, 1.0f, 1.0f, 1.0f); + _has_normals = true; _source_geometry = (PandaNode *)NULL; _source_frame.set(0.0f, 0.0f, 0.0f, 0.0f); } @@ -64,10 +65,18 @@ generate() { float top = _frame[3]; CPT(GeomVertexFormat) format; - if (_has_uvs) { - format = GeomVertexFormat::get_v3cpt2(); + if (_has_normals) { + if (_has_uvs) { + format = GeomVertexFormat::get_v3n3cpt2(); + } else { + format = GeomVertexFormat::get_v3n3cp(); + } } else { - format = GeomVertexFormat::get_v3cp(); + if (_has_uvs) { + format = GeomVertexFormat::get_v3cpt2(); + } else { + format = GeomVertexFormat::get_v3cp(); + } } PT(GeomVertexData) vdata = new GeomVertexData @@ -93,7 +102,16 @@ generate() { texcoord.add_data2f(_ur[0], _ll[1]); } + if (_has_normals) { + GeomVertexWriter normal(vdata, InternalName::get_normal()); + normal.add_data3f(LVector3f::back()); + normal.add_data3f(LVector3f::back()); + normal.add_data3f(LVector3f::back()); + normal.add_data3f(LVector3f::back()); + } + PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static); + strip->set_shade_model(Geom::SM_uniform); strip->add_next_vertices(4); strip->close_primitive(); diff --git a/panda/src/grutil/cardMaker.h b/panda/src/grutil/cardMaker.h index a0203a25de..f254dc9ea0 100644 --- a/panda/src/grutil/cardMaker.h +++ b/panda/src/grutil/cardMaker.h @@ -47,6 +47,8 @@ PUBLISHED: INLINE void set_color(float r, float g, float b, float a); INLINE void set_color(const Colorf &color); + INLINE void set_has_normals(bool flag); + INLINE void set_source_geometry(PandaNode *node, const LVecBase4f &frame); INLINE void clear_source_geometry(); @@ -62,6 +64,8 @@ private: bool _has_color; Colorf _color; + bool _has_normals; + PT(PandaNode) _source_geometry; LVecBase4f _source_frame; }; diff --git a/panda/src/pgraph/lensNode.cxx b/panda/src/pgraph/lensNode.cxx index af6d5e54bd..181e7485f4 100644 --- a/panda/src/pgraph/lensNode.cxx +++ b/panda/src/pgraph/lensNode.cxx @@ -22,6 +22,7 @@ #include "bamReader.h" #include "datagram.h" #include "datagramIterator.h" +#include "perspectiveLens.h" #include "geomNode.h" TypeHandle LensNode::_type_handle; @@ -33,7 +34,8 @@ TypeHandle LensNode::_type_handle; //////////////////////////////////////////////////////////////////// LensNode:: LensNode(const string &name) : - PandaNode(name) + PandaNode(name), + _lens(new PerspectiveLens()) { } diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index f10777ab33..75660a23bc 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -3701,24 +3701,15 @@ find_all_texture_stages(const string &name) const { // Description: Sets the geometry at this level and below to render // using the indicated material. // -// This operation copies the given material pointer. If -// the material structure is changed later, it must be -// reapplied via another call to set_material(). +// Previously, this operation made a copy of the +// material structure, but nowadays it assigns the +// pointer directly. //////////////////////////////////////////////////////////////////// void NodePath:: set_material(Material *mat, int priority) { nassertv_always(!is_empty()); nassertv(mat != NULL); - - // We create a temporary Material pointer, a copy of the one we are - // given, to allow the user to monkey with the material and set it - // again later, with the desired effect. If we stored the user's - // pointer directly, it would be bad if the user later modified the - // values within the Material. - PT(Material) temp = new Material(*mat); - const Material *mp = MaterialPool::get_material(temp); - - node()->set_attrib(MaterialAttrib::make(mp), priority); + node()->set_attrib(MaterialAttrib::make(mat), priority); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pnmimage/pnmImage.cxx b/panda/src/pnmimage/pnmImage.cxx index 2074702fba..b87005ef3d 100644 --- a/panda/src/pnmimage/pnmImage.cxx +++ b/panda/src/pnmimage/pnmImage.cxx @@ -394,10 +394,10 @@ make_grayscale(double rc, double gc, double bc) { //////////////////////////////////////////////////////////////////// void PNMImage:: set_maxval(xelval maxval) { - nassertv(maxval > 0.0); + nassertv(maxval > 0); if (maxval != _maxval) { - double ratio = maxval / _maxval; + double ratio = (double)maxval / (double)_maxval; if (is_grayscale()) { for (int y = 0; y < get_y_size(); y++) {