diff --git a/panda/src/display/config_display.cxx b/panda/src/display/config_display.cxx index bc2c7952be..fc6fbeed68 100644 --- a/panda/src/display/config_display.cxx +++ b/panda/src/display/config_display.cxx @@ -260,7 +260,6 @@ ConfigVariableBool sync_video "cheesy estimate of scene complexity. Some drivers may ignore " "this request.")); - //////////////////////////////////////////////////////////////////// // Function: init_libdisplay // Description: Initializes the library. This must be called at diff --git a/panda/src/display/config_display.h b/panda/src/display/config_display.h index 63e0d263e6..1301ca65bf 100644 --- a/panda/src/display/config_display.h +++ b/panda/src/display/config_display.h @@ -28,6 +28,7 @@ #include "configVariableInt.h" #include "configVariableEnum.h" #include "configVariableFilename.h" +#include "coordinateSystem.h" #include "dconfig.h" #include "pvector.h" @@ -84,7 +85,6 @@ extern EXPCL_PANDA ConfigVariableInt multisamples; extern EXPCL_PANDA ConfigVariableDouble background_color; extern EXPCL_PANDA ConfigVariableBool sync_video; - extern EXPCL_PANDA void init_libdisplay(); #endif /* CONFIG_DISPLAY_H */ diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index dde9963452..e52c4d3336 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -39,20 +39,21 @@ PStatCollector GraphicsOutput::_make_current_pcollector("Draw:Make current"); PStatCollector GraphicsOutput::_copy_texture_pcollector("Draw:Copy texture"); struct CubeFaceDef { - CubeFaceDef(const char *name, float h, float p, float r) : - _name(name), _hpr(h, p, r) { } + CubeFaceDef(const char *name, const LPoint3f &look_at, const LVector3f &up) : + _name(name), _look_at(look_at), _up(up) { } const char *_name; - LVecBase3f _hpr; + LPoint3f _look_at; + LVector3f _up; }; static CubeFaceDef cube_faces[6] = { - CubeFaceDef("positive_x", -90, 0, -180), - CubeFaceDef("negative_x", 90, 0, -180), - CubeFaceDef("positive_y", 0, 90, 0), - CubeFaceDef("negative_y", 0, -90, 0), - CubeFaceDef("positive_z", 180, 0, -180), - CubeFaceDef("negative_z", 0, 0, -180), + CubeFaceDef("positive_x", LPoint3f(1, 0, 0), LVector3f(0, -1, 0)), + CubeFaceDef("negative_x", LPoint3f(-1, 0, 0), LVector3f(0, -1, 0)), + CubeFaceDef("positive_y", LPoint3f(0, 1, 0), LVector3f(0, 0, 1)), + CubeFaceDef("negative_y", LPoint3f(0, -1, 0), LVector3f(0, 0, -1)), + CubeFaceDef("positive_z", LPoint3f(0, 0, 1), LVector3f(0, -1, 0)), + CubeFaceDef("negative_z", LPoint3f(0, 0, -1), LVector3f(0, -1, 0)) }; //////////////////////////////////////////////////////////////////// @@ -655,7 +656,7 @@ make_cube_map(const string &name, int size, bool to_ram, camera->set_lens(lens); camera->set_camera_mask(camera_mask); NodePath camera_np = camera_rig.attach_new_node(camera); - camera_np.set_hpr(cube_faces[i]._hpr); + camera_np.look_at(cube_faces[i]._look_at, cube_faces[i]._up); DisplayRegion *dr = buffer->make_display_region(); dr->set_cube_map_index(i); diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index b9fe24f40a..f2b3245704 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/panda/src/display/graphicsStateGuardian.I @@ -432,6 +432,19 @@ get_color_scale_via_lighting() const { return _color_scale_via_lighting; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_coordinate_system +// Access: Published +// Description: Returns the coordinate system in effect on this +// particular gsg. Normally, this will be the default +// coordinate system, but it might be set differently at +// runtime. +//////////////////////////////////////////////////////////////////// +INLINE CoordinateSystem GraphicsStateGuardian:: +get_coordinate_system() const { + return _coordinate_system; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::set_scene @@ -696,19 +709,6 @@ pop_display_region(DisplayRegionStack &node) { node._stack_level = -1; } -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::get_coordinate_system -// Access: Public -// Description: Returns the coordinate system in effect on this -// particular gsg. Normally, this will be the default -// coordinate system, but it might be set differently at -// runtime. -//////////////////////////////////////////////////////////////////// -INLINE CoordinateSystem GraphicsStateGuardian:: -get_coordinate_system() const { - return _coordinate_system; -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::get_cs_transform // Access: Public diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 8a4a6750c8..5ae03bbfc0 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -100,6 +100,7 @@ GraphicsStateGuardian(const FrameBufferProperties &properties, _coordinate_system = CS_invalid; _external_transform = TransformState::make_identity(); _internal_transform = TransformState::make_identity(); + set_coordinate_system(get_default_coordinate_system()); _current_display_region = (DisplayRegion*)0L; @@ -199,6 +200,58 @@ get_supported_geom_rendering() const { return _supported_geom_rendering; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::set_coordinate_system +// Access: Published +// Description: Changes the coordinate system in effect on this +// particular gsg. This is also called the "external" +// coordinate system, since it is the coordinate system +// used by the scene graph, external to to GSG. +// +// Normally, this will be the default coordinate system, +// but it might be set differently at runtime. +//////////////////////////////////////////////////////////////////// +void GraphicsStateGuardian:: +set_coordinate_system(CoordinateSystem cs) { + _coordinate_system = cs; + + // Changing the external coordinate system changes the cs_transform. + if (_internal_coordinate_system == CS_default || + _internal_coordinate_system == _coordinate_system) { + _cs_transform = TransformState::make_identity(); + _inv_cs_transform = TransformState::make_identity(); + + } else { + _cs_transform = + TransformState::make_mat + (LMatrix4f::convert_mat(_coordinate_system, + _internal_coordinate_system)); + _inv_cs_transform = + TransformState::make_mat + (LMatrix4f::convert_mat(_internal_coordinate_system, + _coordinate_system)); + } + _internal_transform = _cs_transform->compose(_external_transform); +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_internal_coordinate_system +// Access: Published, Virtual +// Description: Returns the coordinate system used internally by the +// GSG. This may be the same as the external coordinate +// system reported by get_coordinate_system(), or it may +// be something different. +// +// In any case, vertices that have been transformed +// before being handed to the GSG (that is, vertices +// with a contents value of C_clip_point) will be +// expected to be in this coordinate system. +//////////////////////////////////////////////////////////////////// +CoordinateSystem GraphicsStateGuardian:: +get_internal_coordinate_system() const { + return _internal_coordinate_system; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::reset // Access: Public, Virtual @@ -934,58 +987,6 @@ void GraphicsStateGuardian:: framebuffer_release_texture(GraphicsOutput *, Texture *) { } -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::set_coordinate_system -// Access: Public -// Description: Changes the coordinate system in effect on this -// particular gsg. This is also called the "external" -// coordinate system, since it is the coordinate system -// used by the scene graph, external to to GSG. -// -// Normally, this will be the default coordinate system, -// but it might be set differently at runtime. -//////////////////////////////////////////////////////////////////// -void GraphicsStateGuardian:: -set_coordinate_system(CoordinateSystem cs) { - _coordinate_system = cs; - - // Changing the external coordinate system changes the cs_transform. - if (_internal_coordinate_system == CS_default || - _internal_coordinate_system == _coordinate_system) { - _cs_transform = TransformState::make_identity(); - _inv_cs_transform = TransformState::make_identity(); - - } else { - _cs_transform = - TransformState::make_mat - (LMatrix4f::convert_mat(_coordinate_system, - _internal_coordinate_system)); - _inv_cs_transform = - TransformState::make_mat - (LMatrix4f::convert_mat(_internal_coordinate_system, - _coordinate_system)); - } - _internal_transform = _cs_transform->compose(_external_transform); -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::get_internal_coordinate_system -// Access: Public, Virtual -// Description: Returns the coordinate system used internally by the -// GSG. This may be the same as the external coordinate -// system reported by get_coordinate_system(), or it may -// be something different. -// -// In any case, vertices that have been transformed -// before being handed to the GSG (that is, vertices -// with a contents value of C_clip_point) will be -// expected to be in this coordinate system. -//////////////////////////////////////////////////////////////////// -CoordinateSystem GraphicsStateGuardian:: -get_internal_coordinate_system() const { - return _internal_coordinate_system; -} - //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::issue_transform // Access: Public, Virtual diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 1f2f6c4aa7..c3c27e7a9b 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -116,6 +116,10 @@ PUBLISHED: INLINE bool get_color_scale_via_lighting() const; + void set_coordinate_system(CoordinateSystem cs); + INLINE CoordinateSystem get_coordinate_system() const; + virtual CoordinateSystem get_internal_coordinate_system() const; + public: INLINE bool set_scene(SceneSetup *scene_setup); INLINE SceneSetup *get_scene() const; @@ -204,10 +208,6 @@ public: INLINE DisplayRegionStack push_display_region(const DisplayRegion *dr); INLINE void pop_display_region(DisplayRegionStack &node); - void set_coordinate_system(CoordinateSystem cs); - INLINE CoordinateSystem get_coordinate_system() const; - virtual CoordinateSystem get_internal_coordinate_system() const; - INLINE const TransformState *get_cs_transform() const; INLINE const TransformState *get_inv_cs_transform() const; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index eb2919dc64..8b61c783e8 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -2290,16 +2290,15 @@ do_issue_texture() { _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); texcoords_3d = true; - CPT(TransformState) camera_transform = _cs_transform->compose(_scene_setup->get_camera_transform())->compose(_inv_cs_transform); - CPT(TransformState) rotate_transform = invert_z->compose(camera_transform); - tex_mat = tex_mat->compose(rotate_transform->set_pos(LVecBase3f::zero())); + CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform); + tex_mat = tex_mat->compose(camera_transform->set_pos(LVecBase3f::zero())); } break; case TexGenAttrib::M_eye_cube_map: _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); - tex_mat = tex_mat->compose(invert_z); + tex_mat = tex_mat->compose(_inv_cs_transform); texcoords_3d = true; break; @@ -2312,23 +2311,22 @@ do_issue_texture() { _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL); texcoords_3d = true; - CPT(TransformState) camera_transform = _cs_transform->compose(_scene_setup->get_camera_transform())->compose(_inv_cs_transform); - CPT(TransformState) rotate_transform = invert_z->compose(camera_transform); - tex_mat = tex_mat->compose(rotate_transform->set_pos(LVecBase3f::zero())); + CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform); + tex_mat = tex_mat->compose(camera_transform->set_pos(LVecBase3f::zero())); } break; case TexGenAttrib::M_eye_normal: _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL); - tex_mat = tex_mat->compose(invert_z); texcoords_3d = true; + tex_mat = tex_mat->compose(_inv_cs_transform); break; case TexGenAttrib::M_world_position: // To achieve world position, we must transform camera // coordinates to world coordinates; i.e. apply the - // inverse root_transform. + // camera transform. { _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index f830f381c5..cb2642cc00 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -4241,25 +4241,47 @@ finish_modify_state() { break; case TexGenAttrib::M_eye_cube_map: + if (_supports_cube_map) { + // We need to rotate the normals out of GL's coordinate + // system and into the user's coordinate system. We do this + // by composing a transform onto the texture matrix. + LMatrix4f mat = _inv_cs_transform->get_mat(); + mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f)); + GLP(MatrixMode)(GL_TEXTURE); + GLP(MultMatrixf)(mat.get_data()); + + // Now we need to reset the texture matrix next time + // around to undo this. + _tex_gen_modifies_mat = true; + + GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + GLP(Enable)(GL_TEXTURE_GEN_S); + GLP(Enable)(GL_TEXTURE_GEN_T); + GLP(Enable)(GL_TEXTURE_GEN_R); + force_normal = true; + } + break; + case TexGenAttrib::M_world_cube_map: if (_supports_cube_map) { - if (mode != TexGenAttrib::M_eye_cube_map) { - // We dynamically transform normals from eye space to - // world space by applying the appropriate rotation - // transform to the current texture matrix. Although it's - // tempting to try, we can't safely convert to object - // space, since this method doesn't get called with each - // different object. - CPT(TransformState) camera_transform = _cs_transform->compose(_scene_setup->get_camera_transform())->compose(_inv_cs_transform); - LMatrix4f mat = camera_transform->get_mat(); - mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f)); - GLP(MatrixMode)(GL_TEXTURE); - GLP(MultMatrixf)(mat.get_data()); + // We dynamically transform normals from eye space to world + // space by applying the appropriate rotation transform to + // the current texture matrix. Unlike M_world_position, we + // can't achieve this effect by monkeying with the modelview + // transform, since the current modelview doesn't affect + // GL_REFLECTION_MAP. + CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform); - // Now we need to reset the texture matrix next time - // around to undo this. - _tex_gen_modifies_mat = true; - } + LMatrix4f mat = camera_transform->get_mat(); + mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f)); + GLP(MatrixMode)(GL_TEXTURE); + GLP(MultMatrixf)(mat.get_data()); + + // Now we need to reset the texture matrix next time + // around to undo this. + _tex_gen_modifies_mat = true; GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); @@ -4272,27 +4294,47 @@ finish_modify_state() { break; case TexGenAttrib::M_eye_normal: + if (_supports_cube_map) { + // We need to rotate the normals out of GL's coordinate + // system and into the user's coordinate system. We do this + // by composing a transform onto the texture matrix. + LMatrix4f mat = _inv_cs_transform->get_mat(); + mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f)); + GLP(MatrixMode)(GL_TEXTURE); + GLP(MultMatrixf)(mat.get_data()); + + // Now we need to reset the texture matrix next time + // around to undo this. + _tex_gen_modifies_mat = true; + + GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); + GLP(Enable)(GL_TEXTURE_GEN_S); + GLP(Enable)(GL_TEXTURE_GEN_T); + GLP(Enable)(GL_TEXTURE_GEN_R); + force_normal = true; + } + break; + case TexGenAttrib::M_world_normal: if (_supports_cube_map) { - if (mode != TexGenAttrib::M_eye_normal) { - // We dynamically transform normals from eye space to - // world space by applying the appropriate rotation - // transform to the current texture matrix. Although it's - // tempting to try, we can't safely convert to object - // space, since this method doesn't get called with each - // different object. - CPT(TransformState) transform = - _cs_transform->compose(_scene_setup->get_world_transform()); - transform = transform->invert_compose(TransformState::make_identity()); - LMatrix4f mat = transform->get_mat(); - mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f)); - GLP(MatrixMode)(GL_TEXTURE); - GLP(MultMatrixf)(mat.get_data()); + // We dynamically transform normals from eye space to world + // space by applying the appropriate rotation transform to + // the current texture matrix. Unlike M_world_position, we + // can't achieve this effect by monkeying with the modelview + // transform, since the current modelview doesn't affect + // GL_NORMAL_MAP. + CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform); - // Now we need to reset the texture matrix next time - // around to undo this. - _tex_gen_modifies_mat = true; - } + LMatrix4f mat = camera_transform->get_mat(); + mat.set_row(3, LVecBase3f(0.0f, 0.0f, 0.0f)); + GLP(MatrixMode)(GL_TEXTURE); + GLP(MultMatrixf)(mat.get_data()); + + // Now we need to reset the texture matrix next time + // around to undo this. + _tex_gen_modifies_mat = true; GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); diff --git a/panda/src/gobj/texture.I b/panda/src/gobj/texture.I index b97813c00d..00f6abcc16 100644 --- a/panda/src/gobj/texture.I +++ b/panda/src/gobj/texture.I @@ -662,7 +662,7 @@ set_x_size(int x_size) { INLINE void Texture:: set_y_size(int y_size) { if (_y_size != y_size) { - nassertv(_texture_type != Texture::TT_1d_texture); + nassertv(_texture_type != Texture::TT_1d_texture || y_size == 1); _y_size = y_size; clear_ram_image(); } @@ -678,7 +678,9 @@ set_y_size(int y_size) { INLINE void Texture:: set_z_size(int z_size) { if (_z_size != z_size) { - nassertv(_texture_type == Texture::TT_3d_texture); + nassertv(_texture_type == Texture::TT_3d_texture || + (_texture_type == Texture::TT_cube_map && z_size == 6) || + (z_size == 1)); _z_size = z_size; clear_ram_image(); } diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index 038718af74..4857f82967 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -413,6 +413,22 @@ read_pages(const Filename &fullpath_template, int z_size) { clear_ram_image(); + if (z_size == 0) { + switch (_texture_type) { + case TT_1d_texture: + case TT_2d_texture: + z_size = 1; + break; + + case TT_cube_map: + z_size = 6; + break; + + default: + break; + } + } + if (z_size != 0) { set_z_size(z_size); for (int z = 0; z < z_size; z++) { diff --git a/panda/src/linmath/coordinateSystem.cxx b/panda/src/linmath/coordinateSystem.cxx index f10c4ea26c..207d84c729 100644 --- a/panda/src/linmath/coordinateSystem.cxx +++ b/panda/src/linmath/coordinateSystem.cxx @@ -28,8 +28,9 @@ static ConfigVariableEnum default_cs ("coordinate-system", CS_zup_right, - "The default coordinate system to use throughout Panda for rendering, " - "user input, and matrix operations, unless specified otherwise."); + PRC_DESC("The default coordinate system to use throughout Panda for " + "rendering, user input, and matrix operations, unless specified " + "otherwise.")); CoordinateSystem