regularize cube map coordinate systems

This commit is contained in:
David Rose 2005-07-21 18:09:30 +00:00
parent 828307a431
commit 314630126f
11 changed files with 188 additions and 128 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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();
}

View File

@ -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++) {

View File

@ -28,8 +28,9 @@
static ConfigVariableEnum<CoordinateSystem> 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