More code for shader matrix computation
This commit is contained in:
parent
7a4897708e
commit
5fa80f8c40
|
|
@ -105,8 +105,6 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
|
|||
_current_lens = (Lens *)NULL;
|
||||
_projection_mat = TransformState::make_identity();
|
||||
_projection_mat_inv = TransformState::make_identity();
|
||||
_clip_to_view = TransformState::make_identity();
|
||||
_view_to_clip = TransformState::make_identity();
|
||||
|
||||
_needs_reset = true;
|
||||
_is_valid = false;
|
||||
|
|
@ -373,10 +371,6 @@ set_scene(SceneSetup *scene_setup) {
|
|||
return false;
|
||||
}
|
||||
_projection_mat_inv = _projection_mat->get_inverse();
|
||||
_view_to_clip = TransformState::make_mat(_current_lens->
|
||||
get_projection_mat(_coordinate_system, _current_stereo_channel));
|
||||
_clip_to_view = TransformState::make_mat(_current_lens->
|
||||
get_projection_mat_inv(_coordinate_system, _current_stereo_channel));
|
||||
return prepare_lens();
|
||||
}
|
||||
|
||||
|
|
@ -677,177 +671,205 @@ clear(DrawableRegion *clearable) {
|
|||
// shoehorning them into a matrix. In this way, we avoid
|
||||
// the need for a separate routine to fetch these values.
|
||||
//
|
||||
// This routine is actually a simple pcode-interpreter,
|
||||
// and the ShaderMatSpec is actually a small pcode-array.
|
||||
// This makes it possible to express requests for a
|
||||
// large variety of values, and a large variety of
|
||||
// possible conversions.
|
||||
// If "altered" is false, that means you promise that
|
||||
// this ShaderMatSpec has been evaluated before, and that
|
||||
// since the last time this ShaderMatSpec was evaluated,
|
||||
// that no part of the render state has changed except
|
||||
// the external and internal transforms.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
fetch_specified_value(const ShaderContext::ShaderMatSpec &spec, LMatrix4f &result) {
|
||||
pvector<LMatrix4f> stack;
|
||||
int pc = 0;
|
||||
int ac = 0;
|
||||
while (pc < (int)spec._opcodes.size()) {
|
||||
int opcode = spec._opcodes[pc++];
|
||||
switch(opcode) {
|
||||
case ShaderContext::SMO_identity: {
|
||||
stack.push_back(LMatrix4f::ident_mat());
|
||||
break;
|
||||
const LMatrix4f *GraphicsStateGuardian::
|
||||
fetch_specified_value(ShaderContext::ShaderMatSpec &spec, bool altered) {
|
||||
static LMatrix4f acc;
|
||||
const LMatrix4f *val1;
|
||||
const LMatrix4f *val2;
|
||||
static LMatrix4f t1;
|
||||
static LMatrix4f t2;
|
||||
|
||||
switch(spec._func) {
|
||||
case ShaderContext::SMF_compose:
|
||||
val1 = fetch_specified_part(spec._part[0], spec._arg[0], t1);
|
||||
val2 = fetch_specified_part(spec._part[1], spec._arg[1], t2);
|
||||
acc.multiply(*val1, *val2);
|
||||
return &acc;
|
||||
case ShaderContext::SMF_compose_cache_first:
|
||||
if (altered) {
|
||||
spec._cache = *fetch_specified_part(spec._part[0], spec._arg[0], t1);
|
||||
}
|
||||
case ShaderContext::SMO_modelview: {
|
||||
stack.push_back(_internal_transform->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_projection: {
|
||||
stack.push_back(_projection_mat->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_modelproj: {
|
||||
stack.push_back(_internal_transform->get_mat() * _projection_mat->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_window_size: {
|
||||
stack.push_back(LMatrix4f::translate_mat(_current_display_region->get_pixel_width(),
|
||||
_current_display_region->get_pixel_height(),
|
||||
0.0));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_pixel_size: {
|
||||
stack.push_back(LMatrix4f::translate_mat(_current_display_region->get_pixel_width(),
|
||||
_current_display_region->get_pixel_height(),
|
||||
0.0));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_card_center: {
|
||||
int px = _current_display_region->get_pixel_width();
|
||||
int py = _current_display_region->get_pixel_height();
|
||||
stack.push_back(LMatrix4f::translate_mat((px*0.5) / Texture::up_to_power_2(px),
|
||||
(py*0.5) / Texture::up_to_power_2(py),
|
||||
0.0));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_mat_constant_x: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
if (input->get_nodepath().is_empty()) {
|
||||
return false;
|
||||
}
|
||||
stack.push_back(input->get_nodepath().node()->get_transform()->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_vec_constant_x: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
const float *data = input->get_vector().get_data();
|
||||
stack.push_back(LMatrix4f(data[0],data[1],data[2],data[3],
|
||||
data[0],data[1],data[2],data[3],
|
||||
data[0],data[1],data[2],data[3],
|
||||
data[0],data[1],data[2],data[3]));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_world_to_view: {
|
||||
stack.push_back(get_scene()->get_world_transform()->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_world_C: {
|
||||
stack.back() *= get_scene()->get_camera_transform()->get_mat();
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_model_to_view: {
|
||||
stack.push_back(_external_transform->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_model_C: {
|
||||
stack.back() *= invert(_external_transform->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_apiview_to_view: {
|
||||
stack.push_back(_inv_cs_transform->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_apiview_C: {
|
||||
stack.back() *= _cs_transform->get_mat();
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_clip_to_view: {
|
||||
stack.push_back(_clip_to_view->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_clip_C: {
|
||||
stack.back() *= _view_to_clip->get_mat();
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_apiclip_to_view: {
|
||||
stack.push_back(_projection_mat_inv->get_mat() * _inv_cs_transform->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_apiclip_C: {
|
||||
stack.back() *= _cs_transform->get_mat() * _projection_mat->get_mat();
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_x_to_view: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
nassertr(!input->get_nodepath().is_empty(), false);
|
||||
stack.push_back(input->get_nodepath().get_net_transform()->get_mat() *
|
||||
get_scene()->get_world_transform()->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_view_x_C: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
nassertr(!input->get_nodepath().is_empty(), false);
|
||||
stack.back()*= (get_scene()->get_camera_transform()->get_mat() *
|
||||
invert(input->get_nodepath().get_net_transform()->get_mat()));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_apiview_x_to_view: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
nassertr(!input->get_nodepath().is_empty(), false);
|
||||
stack.push_back(LMatrix4f::convert_mat(_internal_coordinate_system, _coordinate_system) *
|
||||
input->get_nodepath().get_net_transform()->get_mat() *
|
||||
get_scene()->get_world_transform()->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_apiview_x_C: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
nassertr(!input->get_nodepath().is_empty(), false);
|
||||
stack.back()*= (get_scene()->get_camera_transform()->get_mat() *
|
||||
invert(input->get_nodepath().get_net_transform()->get_mat()) *
|
||||
LMatrix4f::convert_mat(_coordinate_system, _internal_coordinate_system));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_clip_x_to_view: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
nassertr(!input->get_nodepath().is_empty(), false);
|
||||
Lens *lens = DCAST(LensNode, input->get_nodepath().node())->get_lens();
|
||||
stack.push_back(lens->get_projection_mat_inv(_coordinate_system, _current_stereo_channel) *
|
||||
input->get_nodepath().get_net_transform()->get_mat() *
|
||||
get_scene()->get_world_transform()->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_clip_x_C: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
nassertr(!input->get_nodepath().is_empty(), false);
|
||||
Lens *lens = DCAST(LensNode, input->get_nodepath().node())->get_lens();
|
||||
stack.back()*= (get_scene()->get_camera_transform()->get_mat() *
|
||||
invert(input->get_nodepath().get_net_transform()->get_mat()) *
|
||||
lens->get_projection_mat(_coordinate_system, _current_stereo_channel));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_apiclip_x_to_view: {
|
||||
// NOT IMPLEMENTED
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_apiclip_x_C: {
|
||||
// NOT IMPLEMENTED
|
||||
break;
|
||||
val2 = fetch_specified_part(spec._part[1], spec._arg[1], t2);
|
||||
acc.multiply(spec._cache, *val2);
|
||||
return &acc;
|
||||
case ShaderContext::SMF_compose_cache_second:
|
||||
if (altered) {
|
||||
spec._cache = *fetch_specified_part(spec._part[1], spec._arg[1], t2);
|
||||
}
|
||||
val1 = fetch_specified_part(spec._part[0], spec._arg[0], t1);
|
||||
acc.multiply(*val1, spec._cache);
|
||||
return &acc;
|
||||
case ShaderContext::SMF_first:
|
||||
return fetch_specified_part(spec._part[0], spec._arg[0], t1);
|
||||
default:
|
||||
// should never get here
|
||||
return &LMatrix4f::ident_mat();
|
||||
}
|
||||
}
|
||||
|
||||
case ShaderContext::SMO_transpose:
|
||||
stack.back().transpose_in_place();
|
||||
break;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::fetch_specified_part
|
||||
// Access: Public
|
||||
// Description: See fetch_specified_value
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f *GraphicsStateGuardian::
|
||||
fetch_specified_part(ShaderContext::ShaderMatInput part, InternalName *name, LMatrix4f &t) {
|
||||
switch(part) {
|
||||
case ShaderContext::SMO_identity: {
|
||||
return &LMatrix4f::ident_mat();
|
||||
}
|
||||
case ShaderContext::SMO_window_size: {
|
||||
t = LMatrix4f::translate_mat(_current_display_region->get_pixel_width(),
|
||||
_current_display_region->get_pixel_height(),
|
||||
0.0);
|
||||
return &t;
|
||||
}
|
||||
case ShaderContext::SMO_pixel_size: {
|
||||
t = LMatrix4f::translate_mat(_current_display_region->get_pixel_width(),
|
||||
_current_display_region->get_pixel_height(),
|
||||
0.0);
|
||||
return &t;
|
||||
}
|
||||
case ShaderContext::SMO_card_center: {
|
||||
int px = _current_display_region->get_pixel_width();
|
||||
int py = _current_display_region->get_pixel_height();
|
||||
t = LMatrix4f::translate_mat((px*0.5) / Texture::up_to_power_2(px),
|
||||
(py*0.5) / Texture::up_to_power_2(py),
|
||||
0.0);
|
||||
return &t;
|
||||
}
|
||||
case ShaderContext::SMO_mat_constant_x: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(name);
|
||||
if (input->get_nodepath().is_empty()) {
|
||||
return &LMatrix4f::ident_mat();
|
||||
}
|
||||
return &(input->get_nodepath().node()->get_transform()->get_mat());
|
||||
}
|
||||
case ShaderContext::SMO_vec_constant_x: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(name);
|
||||
const float *data = input->get_vector().get_data();
|
||||
t = LMatrix4f(data[0],data[1],data[2],data[3],
|
||||
data[0],data[1],data[2],data[3],
|
||||
data[0],data[1],data[2],data[3],
|
||||
data[0],data[1],data[2],data[3]);
|
||||
return &t;
|
||||
}
|
||||
case ShaderContext::SMO_world_to_view: {
|
||||
return &(get_scene()->get_world_transform()->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_world: {
|
||||
return &(get_scene()->get_camera_transform()->get_mat());
|
||||
}
|
||||
case ShaderContext::SMO_model_to_view: {
|
||||
return &(_external_transform->get_mat());
|
||||
}
|
||||
case ShaderContext::SMO_view_to_model: {
|
||||
// DANGER: SLOW AND NOT CACHEABLE!
|
||||
t.invert_from(_external_transform->get_mat());
|
||||
return &t;
|
||||
}
|
||||
case ShaderContext::SMO_apiview_to_view: {
|
||||
return &(_inv_cs_transform->get_mat());
|
||||
}
|
||||
case ShaderContext::SMO_view_to_apiview: {
|
||||
return &(_cs_transform->get_mat());
|
||||
}
|
||||
case ShaderContext::SMO_clip_to_view: {
|
||||
if (_current_lens->get_coordinate_system() == _coordinate_system) {
|
||||
return &(_current_lens->get_projection_mat_inv(_current_stereo_channel));
|
||||
} else {
|
||||
t = _current_lens->get_projection_mat_inv(_current_stereo_channel) *
|
||||
LMatrix4f::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system);
|
||||
return &t;
|
||||
}
|
||||
}
|
||||
result = stack.back();
|
||||
return true;
|
||||
case ShaderContext::SMO_view_to_clip: {
|
||||
if (_current_lens->get_coordinate_system() == _coordinate_system) {
|
||||
return &(_current_lens->get_projection_mat(_current_stereo_channel));
|
||||
} else {
|
||||
t = LMatrix4f::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) *
|
||||
_current_lens->get_projection_mat(_current_stereo_channel);
|
||||
return &t;
|
||||
}
|
||||
}
|
||||
case ShaderContext::SMO_apiclip_to_view: {
|
||||
t = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat();
|
||||
return &t;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_apiclip: {
|
||||
t = _cs_transform->get_mat() * _projection_mat->get_mat();
|
||||
return &t;
|
||||
}
|
||||
case ShaderContext::SMO_view_x_to_view: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(name);
|
||||
nassertr(!input->get_nodepath().is_empty(), &LMatrix4f::ident_mat());
|
||||
t = input->get_nodepath().get_net_transform()->get_mat() *
|
||||
get_scene()->get_world_transform()->get_mat();
|
||||
return &t;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_view_x: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(name);
|
||||
nassertr(!input->get_nodepath().is_empty(), &LMatrix4f::ident_mat());
|
||||
t = get_scene()->get_camera_transform()->get_mat() *
|
||||
invert(input->get_nodepath().get_net_transform()->get_mat());
|
||||
return &t;
|
||||
}
|
||||
case ShaderContext::SMO_apiview_x_to_view: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(name);
|
||||
nassertr(!input->get_nodepath().is_empty(), &LMatrix4f::ident_mat());
|
||||
t = LMatrix4f::convert_mat(_internal_coordinate_system, _coordinate_system) *
|
||||
input->get_nodepath().get_net_transform()->get_mat() *
|
||||
get_scene()->get_world_transform()->get_mat();
|
||||
return &t;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_apiview_x: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(name);
|
||||
nassertr(!input->get_nodepath().is_empty(), &LMatrix4f::ident_mat());
|
||||
t = (get_scene()->get_camera_transform()->get_mat() *
|
||||
invert(input->get_nodepath().get_net_transform()->get_mat()) *
|
||||
LMatrix4f::convert_mat(_coordinate_system, _internal_coordinate_system));
|
||||
return &t;
|
||||
}
|
||||
case ShaderContext::SMO_clip_x_to_view: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(name);
|
||||
nassertr(!input->get_nodepath().is_empty(), &LMatrix4f::ident_mat());
|
||||
Lens *lens = DCAST(LensNode, input->get_nodepath().node())->get_lens();
|
||||
t = lens->get_projection_mat_inv(_current_stereo_channel) *
|
||||
LMatrix4f::convert_mat(lens->get_coordinate_system(), _coordinate_system) *
|
||||
input->get_nodepath().get_net_transform()->get_mat() *
|
||||
get_scene()->get_world_transform()->get_mat();
|
||||
return &t;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_clip_x: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(name);
|
||||
nassertr(!input->get_nodepath().is_empty(), &LMatrix4f::ident_mat());
|
||||
Lens *lens = DCAST(LensNode, input->get_nodepath().node())->get_lens();
|
||||
t = get_scene()->get_camera_transform()->get_mat() *
|
||||
invert(input->get_nodepath().get_net_transform()->get_mat()) *
|
||||
LMatrix4f::convert_mat(_coordinate_system, lens->get_coordinate_system()) *
|
||||
lens->get_projection_mat(_current_stereo_channel);
|
||||
return &t;
|
||||
}
|
||||
case ShaderContext::SMO_apiclip_x_to_view: {
|
||||
// NOT IMPLEMENTED
|
||||
return &LMatrix4f::ident_mat();
|
||||
}
|
||||
case ShaderContext::SMO_view_to_apiclip_x: {
|
||||
// NOT IMPLEMENTED
|
||||
return &LMatrix4f::ident_mat();
|
||||
}
|
||||
default:
|
||||
// should never get here
|
||||
return &LMatrix4f::ident_mat();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -159,7 +159,8 @@ public:
|
|||
|
||||
void clear(DrawableRegion *clearable);
|
||||
|
||||
bool fetch_specified_value(const ShaderContext::ShaderMatSpec &spec, LMatrix4f &result);
|
||||
const LMatrix4f *fetch_specified_value(ShaderContext::ShaderMatSpec &spec, bool altered);
|
||||
const LMatrix4f *fetch_specified_part(ShaderContext::ShaderMatInput input, InternalName *name, LMatrix4f &t);
|
||||
|
||||
virtual void prepare_display_region(DisplayRegion *dr,
|
||||
Lens::StereoChannel stereo_channel);
|
||||
|
|
@ -295,8 +296,6 @@ protected:
|
|||
CPT(Lens) _current_lens;
|
||||
CPT(TransformState) _projection_mat;
|
||||
CPT(TransformState) _projection_mat_inv;
|
||||
CPT(TransformState) _view_to_clip;
|
||||
CPT(TransformState) _clip_to_view;
|
||||
|
||||
CoordinateSystem _coordinate_system;
|
||||
CoordinateSystem _internal_coordinate_system;
|
||||
|
|
|
|||
|
|
@ -2763,8 +2763,9 @@ do_issue_transform() {
|
|||
do_auto_rescale_normal();
|
||||
}
|
||||
|
||||
if (_current_shader_context)
|
||||
if (_current_shader_context) {
|
||||
_current_shader_context->issue_parameters(this, false);
|
||||
}
|
||||
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -442,13 +442,17 @@ unbind()
|
|||
// Description: This function gets called whenever the RenderState
|
||||
// or TransformState has changed, but the ShaderExpansion
|
||||
// itself has not changed. It loads new values into the
|
||||
// shader's parameters. The flag "all" is false if the
|
||||
// only thing that has changed is the modelview matrix.
|
||||
// In this case, only the transform-dependent parameters
|
||||
// are reloaded.
|
||||
// shader's parameters.
|
||||
//
|
||||
// If "altered" is false, that means you promise that
|
||||
// the parameters for this shader context have already
|
||||
// been issued once, and that since the last time the
|
||||
// parameters were issued, no part of the render
|
||||
// state has changed except the external and internal
|
||||
// transforms.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
issue_parameters(GSG *gsg, bool all)
|
||||
issue_parameters(GSG *gsg, bool altered)
|
||||
{
|
||||
#ifdef HAVE_CGGL
|
||||
if (_cg_context == 0) {
|
||||
|
|
@ -456,11 +460,11 @@ issue_parameters(GSG *gsg, bool all)
|
|||
}
|
||||
|
||||
for (int i=0; i<(int)_mat_spec.size(); i++) {
|
||||
if (all || _mat_spec[i]._trans_dependent) {
|
||||
LMatrix4f result;
|
||||
if (altered || _mat_spec[i]._trans_dependent) {
|
||||
CGparameter p = (CGparameter)(_mat_spec[i]._parameter);
|
||||
if (gsg->fetch_specified_value(_mat_spec[i], result)) {
|
||||
const float *data = result.get_data();
|
||||
const LMatrix4f *val = gsg->fetch_specified_value(_mat_spec[i], altered);
|
||||
if (val) {
|
||||
const float *data = val->get_data();
|
||||
switch (_mat_spec[i]._piece) {
|
||||
case SMP_whole: cgGLSetMatrixParameterfc(p, data); break;
|
||||
case SMP_transpose: cgGLSetMatrixParameterfr(p, data); break;
|
||||
|
|
|
|||
|
|
@ -443,34 +443,3 @@ operator << (ostream &out, const Lens &lens) {
|
|||
return out;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_projection_mat
|
||||
// Access: Published
|
||||
// Description: Returns the complete transformation matrix from a 3-d
|
||||
// point in space to a point on the film, if such a
|
||||
// matrix exists, or the identity matrix if the lens is
|
||||
// nonlinear, in the specified coordinate system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f Lens::
|
||||
get_projection_mat(CoordinateSystem cs, StereoChannel channel) const {
|
||||
return
|
||||
LMatrix4f::convert_mat(cs, _cs) *
|
||||
get_projection_mat(channel) *
|
||||
LMatrix4f::convert_mat(CS_yup_right, cs);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_projection_mat_inv
|
||||
// Access: Published
|
||||
// Description: Returns the matrix that transforms from a 2-d point
|
||||
// on the film to a 3-d vector in space, if such a
|
||||
// matrix exists, in the specified coordinate system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f Lens::
|
||||
get_projection_mat_inv(CoordinateSystem cs, StereoChannel channel) const {
|
||||
return
|
||||
LMatrix4f::convert_mat(cs, CS_yup_right) *
|
||||
get_projection_mat_inv(channel) *
|
||||
LMatrix4f::convert_mat(_cs, cs);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -155,9 +155,6 @@ PUBLISHED:
|
|||
const LMatrix4f &get_projection_mat(StereoChannel channel = SC_mono) const;
|
||||
const LMatrix4f &get_projection_mat_inv(StereoChannel channel = SC_mono) const;
|
||||
|
||||
INLINE const LMatrix4f get_projection_mat(CoordinateSystem cs, StereoChannel channel) const;
|
||||
INLINE const LMatrix4f get_projection_mat_inv(CoordinateSystem cs, StereoChannel channel) const;
|
||||
|
||||
const LMatrix4f &get_film_mat() const;
|
||||
const LMatrix4f &get_film_mat_inv() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -171,35 +171,88 @@ cp_errchk_parameter_sampler(ShaderArgInfo &p)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::cp_parse_trans_clause
|
||||
// Function: ShaderContext::cp_parse_trans_clause
|
||||
// Access: Public
|
||||
// Description: Parses a single clause of a "trans" parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ShaderContext::
|
||||
cp_parse_trans_clause(ShaderArgInfo &p, ShaderMatSpec &spec, const vector_string &pieces,
|
||||
int &next, ShaderMatOp ofop, ShaderMatOp op) {
|
||||
cp_parse_trans_clause(ShaderArgInfo &p, ShaderMatSpec &spec,
|
||||
int part, const vector_string &pieces,
|
||||
int &next, ShaderMatInput ofop, ShaderMatInput op) {
|
||||
if (pieces[next+1]=="of") {
|
||||
if (pieces[next+2]=="") {
|
||||
cp_report_error(p, "'of' should be followed by a name");
|
||||
return false;
|
||||
}
|
||||
if (ofop != SMO_noop) {
|
||||
spec._opcodes.push_back(ofop);
|
||||
spec._args.push_back(InternalName::make(pieces[next+2]));
|
||||
}
|
||||
spec._part[part] = ofop;
|
||||
spec._arg[part] = InternalName::make(pieces[next+2]);
|
||||
next += 3;
|
||||
return true;
|
||||
} else {
|
||||
if (op != SMO_noop) {
|
||||
spec._opcodes.push_back(op);
|
||||
}
|
||||
spec._part[part] = op;
|
||||
spec._arg[part] = NULL;
|
||||
next += 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::compile_parameter
|
||||
// Function: ShaderContext::cp_optimize_mat_spec
|
||||
// Access: Public
|
||||
// Description: Analyzes a ShaderMatSpec and decides what it should
|
||||
// use its cache for. It can cache the results of any
|
||||
// one opcode, or, it can cache the entire result. This
|
||||
// routine needs to be smart enough to know which
|
||||
// data items can be correctly cached, and which cannot.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ShaderContext::
|
||||
cp_optimize_mat_spec(ShaderMatSpec &spec) {
|
||||
|
||||
// If we're composing with identity, simplify.
|
||||
if (spec._func == SMF_compose) {
|
||||
if (spec._part[1] == SMO_identity) {
|
||||
spec._func = SMF_first;
|
||||
}
|
||||
}
|
||||
if (spec._func == SMF_compose) {
|
||||
if (spec._part[0] == SMO_identity) {
|
||||
spec._func = SMF_first;
|
||||
spec._part[0] = spec._part[1];
|
||||
spec._arg[0] = spec._arg[1];
|
||||
}
|
||||
}
|
||||
|
||||
// See if either half can be cached.
|
||||
bool can_cache_part0 = true;
|
||||
bool can_cache_part1 = true;
|
||||
if ((spec._part[0] == SMO_model_to_view)||
|
||||
(spec._part[0] == SMO_view_to_model)) {
|
||||
can_cache_part0 = false;
|
||||
}
|
||||
if ((spec._part[1] == SMO_model_to_view)||
|
||||
(spec._part[1] == SMO_view_to_model)) {
|
||||
can_cache_part1 = false;
|
||||
}
|
||||
|
||||
// See if we can use a compose-with-cache variant.
|
||||
if (spec._func == SMF_compose) {
|
||||
if (can_cache_part0) {
|
||||
spec._func = SMF_compose_cache_first;
|
||||
} else if (can_cache_part1) {
|
||||
spec._func = SMF_compose_cache_second;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine transform-dependence.
|
||||
if (can_cache_part0 && can_cache_part1) {
|
||||
spec._trans_dependent = false;
|
||||
} else {
|
||||
spec._trans_dependent = true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShaderContext::compile_parameter
|
||||
// Access: Public
|
||||
// Description: Analyzes a parameter and decides how to
|
||||
// bind the parameter to some part of panda's
|
||||
|
|
@ -377,14 +430,14 @@ compile_parameter(void *reference,
|
|||
|
||||
ShaderMatSpec bind;
|
||||
bind._parameter = reference;
|
||||
bind._trans_dependent = false;
|
||||
bind._func = SMF_compose;
|
||||
|
||||
int next = 1;
|
||||
pieces.push_back("");
|
||||
|
||||
// Decide whether this is a matrix or vector.
|
||||
if (pieces[0]=="trans") bind._piece = SMP_whole;
|
||||
else if (pieces[0]=="tpose") bind._piece = SMP_whole;
|
||||
else if (pieces[0]=="tpose") bind._piece = SMP_transpose;
|
||||
else if (pieces[0]=="row0") bind._piece = SMP_row0;
|
||||
else if (pieces[0]=="row1") bind._piece = SMP_row1;
|
||||
else if (pieces[0]=="row2") bind._piece = SMP_row2;
|
||||
|
|
@ -393,7 +446,7 @@ compile_parameter(void *reference,
|
|||
else if (pieces[0]=="col1") bind._piece = SMP_col1;
|
||||
else if (pieces[0]=="col2") bind._piece = SMP_col2;
|
||||
else if (pieces[0]=="col3") bind._piece = SMP_col3;
|
||||
if (bind._piece == SMP_whole) {
|
||||
if ((bind._piece == SMP_whole)||(bind._piece == SMP_transpose)) {
|
||||
if (!cp_errchk_parameter_float(p, 16, 16)) return false;
|
||||
} else {
|
||||
if (!cp_errchk_parameter_float(p, 4, 4)) return false;
|
||||
|
|
@ -405,21 +458,22 @@ compile_parameter(void *reference,
|
|||
cp_report_error(p, "argument missing");
|
||||
return false;
|
||||
} else if (pieces[next] == "world") {
|
||||
bind._opcodes.push_back(SMO_world_to_view);
|
||||
bind._part[0] = SMO_world_to_view;
|
||||
bind._arg[0] = NULL;
|
||||
next += 1;
|
||||
} else if (pieces[next] == "model") {
|
||||
ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_x_to_view, SMO_model_to_view);
|
||||
ok &= cp_parse_trans_clause(p, bind, 0, pieces, next, SMO_view_x_to_view, SMO_model_to_view);
|
||||
} else if (pieces[next] == "clip") {
|
||||
ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_clip_x_to_view, SMO_clip_to_view);
|
||||
ok &= cp_parse_trans_clause(p, bind, 0, pieces, next, SMO_clip_x_to_view, SMO_clip_to_view);
|
||||
} else if (pieces[next] == "view") {
|
||||
ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_x_to_view, SMO_identity);
|
||||
ok &= cp_parse_trans_clause(p, bind, 0, pieces, next, SMO_view_x_to_view, SMO_identity);
|
||||
} else if (pieces[next] == "apiview") {
|
||||
ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_apiview_x_to_view, SMO_apiview_to_view);
|
||||
ok &= cp_parse_trans_clause(p, bind, 0, pieces, next, SMO_apiview_x_to_view, SMO_apiview_to_view);
|
||||
} else if (pieces[next] == "apiclip") {
|
||||
ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_apiclip_x_to_view, SMO_apiclip_to_view);
|
||||
ok &= cp_parse_trans_clause(p, bind, 0, pieces, next, SMO_apiclip_x_to_view, SMO_apiclip_to_view);
|
||||
} else {
|
||||
bind._opcodes.push_back(SMO_view_x_to_view);
|
||||
bind._args.push_back(InternalName::make(pieces[next]));
|
||||
bind._part[0] = SMO_view_x_to_view;
|
||||
bind._arg[0] = InternalName::make(pieces[next]);
|
||||
next += 1;
|
||||
}
|
||||
|
||||
|
|
@ -428,11 +482,6 @@ compile_parameter(void *reference,
|
|||
return false;
|
||||
}
|
||||
|
||||
// Check for transform-dependence.
|
||||
if (bind._opcodes.back() == SMO_model_to_view) {
|
||||
bind._trans_dependent = true;
|
||||
}
|
||||
|
||||
// Check for syntactic well-formed-ness.
|
||||
if (pieces[next] != "to") {
|
||||
cp_report_error(p, "keyword 'to' expected");
|
||||
|
|
@ -446,21 +495,22 @@ compile_parameter(void *reference,
|
|||
cp_report_error(p, "argument missing");
|
||||
return false;
|
||||
} else if (pieces[next] == "world") {
|
||||
bind._opcodes.push_back(SMO_view_to_world_C);
|
||||
bind._part[1] = SMO_view_to_world;
|
||||
bind._arg[1] = NULL;
|
||||
next += 1;
|
||||
} else if (pieces[next] == "model") {
|
||||
ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_to_view_x_C, SMO_view_to_model_C);
|
||||
ok &= cp_parse_trans_clause(p, bind, 1, pieces, next, SMO_view_to_view_x, SMO_view_to_model);
|
||||
} else if (pieces[next] == "clip") {
|
||||
ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_to_clip_x_C, SMO_view_to_clip_C);
|
||||
ok &= cp_parse_trans_clause(p, bind, 1, pieces, next, SMO_view_to_clip_x, SMO_view_to_clip);
|
||||
} else if (pieces[next] == "view") {
|
||||
ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_to_view_x_C, SMO_noop);
|
||||
ok &= cp_parse_trans_clause(p, bind, 1, pieces, next, SMO_view_to_view_x, SMO_identity);
|
||||
} else if (pieces[next] == "apiview") {
|
||||
ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_to_apiview_x_C, SMO_view_to_apiview_C);
|
||||
ok &= cp_parse_trans_clause(p, bind, 1, pieces, next, SMO_view_to_apiview_x, SMO_view_to_apiview);
|
||||
} else if (pieces[next] == "apiclip") {
|
||||
ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_to_apiclip_x_C, SMO_view_to_apiclip_C);
|
||||
ok &= cp_parse_trans_clause(p, bind, 1, pieces, next, SMO_view_to_apiclip_x, SMO_view_to_apiclip);
|
||||
} else {
|
||||
bind._opcodes.push_back(SMO_view_to_view_x_C);
|
||||
bind._args.push_back(InternalName::make(pieces[next]));
|
||||
bind._part[1] = SMO_view_to_view_x;
|
||||
bind._arg[1] = InternalName::make(pieces[next]);
|
||||
next += 1;
|
||||
}
|
||||
|
||||
|
|
@ -469,17 +519,13 @@ compile_parameter(void *reference,
|
|||
return false;
|
||||
}
|
||||
|
||||
// Check for transform-dependence.
|
||||
if (bind._opcodes.back() == SMO_view_to_model_C) {
|
||||
bind._trans_dependent = true;
|
||||
}
|
||||
|
||||
// Check for syntactic well-formed-ness.
|
||||
if (pieces[next] != "") {
|
||||
cp_report_error(p, "end of line expected");
|
||||
return false;
|
||||
}
|
||||
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -494,27 +540,34 @@ compile_parameter(void *reference,
|
|||
}
|
||||
ShaderMatSpec bind;
|
||||
bind._parameter = reference;
|
||||
bind._trans_dependent = false;
|
||||
bind._piece = SMP_row3;
|
||||
bind._func = SMF_first;
|
||||
bind._part[1] = SMO_identity;
|
||||
bind._arg[1] = NULL;
|
||||
if (pieces[1] == "pixelsize") {
|
||||
if (!cp_errchk_parameter_float(p, 2, 2)) {
|
||||
return false;
|
||||
}
|
||||
bind._opcodes.push_back(SMO_pixel_size);
|
||||
bind._part[0] = SMO_pixel_size;
|
||||
bind._arg[0] = NULL;
|
||||
} else if (pieces[1] == "windowsize") {
|
||||
if (!cp_errchk_parameter_float(p, 2, 2)) {
|
||||
return false;
|
||||
}
|
||||
bind._opcodes.push_back(SMO_window_size);
|
||||
bind._part[0] = SMO_window_size;
|
||||
bind._arg[0] = NULL;
|
||||
} else if (pieces[1] == "cardcenter") {
|
||||
if (!cp_errchk_parameter_float(p, 2, 2)) {
|
||||
return false;
|
||||
}
|
||||
bind._opcodes.push_back(SMO_card_center);
|
||||
bind._part[0] = SMO_card_center;
|
||||
bind._arg[0] = NULL;
|
||||
} else {
|
||||
cp_report_error(p,"unknown system parameter");
|
||||
return false;
|
||||
}
|
||||
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -561,20 +614,26 @@ compile_parameter(void *reference,
|
|||
case SAT_float4: {
|
||||
ShaderMatSpec bind;
|
||||
bind._parameter = reference;
|
||||
bind._trans_dependent = false;
|
||||
bind._piece = SMP_row3;
|
||||
bind._opcodes.push_back(SMO_vec_constant_x);
|
||||
bind._args.push_back(InternalName::make(pieces[1]));
|
||||
bind._func = SMF_first;
|
||||
bind._part[0] = SMO_vec_constant_x;
|
||||
bind._arg[0] = InternalName::make(pieces[1]);
|
||||
bind._part[1] = SMO_identity;
|
||||
bind._arg[1] = NULL;
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
break;
|
||||
}
|
||||
case SAT_float4x4: {
|
||||
ShaderMatSpec bind;
|
||||
bind._parameter = reference;
|
||||
bind._trans_dependent = false;
|
||||
bind._piece = SMP_whole;
|
||||
bind._opcodes.push_back(SMO_mat_constant_x);
|
||||
bind._args.push_back(InternalName::make(pieces[1]));
|
||||
bind._func = SMF_first;
|
||||
bind._part[0] = SMO_vec_constant_x;
|
||||
bind._arg[0] = InternalName::make(pieces[1]);
|
||||
bind._part[1] = SMO_identity;
|
||||
bind._arg[1] = NULL;
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,44 @@ public:
|
|||
SHADER_type_both=2,
|
||||
};
|
||||
|
||||
enum ShaderMatInput {
|
||||
SMO_identity,
|
||||
|
||||
SMO_window_size,
|
||||
SMO_pixel_size,
|
||||
SMO_card_center,
|
||||
|
||||
SMO_mat_constant_x,
|
||||
SMO_vec_constant_x,
|
||||
|
||||
SMO_world_to_view,
|
||||
SMO_view_to_world,
|
||||
|
||||
SMO_model_to_view,
|
||||
SMO_view_to_model,
|
||||
|
||||
SMO_apiview_to_view,
|
||||
SMO_view_to_apiview,
|
||||
|
||||
SMO_clip_to_view,
|
||||
SMO_view_to_clip,
|
||||
|
||||
SMO_apiclip_to_view,
|
||||
SMO_view_to_apiclip,
|
||||
|
||||
SMO_view_x_to_view,
|
||||
SMO_view_to_view_x,
|
||||
|
||||
SMO_apiview_x_to_view,
|
||||
SMO_view_to_apiview_x,
|
||||
|
||||
SMO_clip_x_to_view,
|
||||
SMO_view_to_clip_x,
|
||||
|
||||
SMO_apiclip_x_to_view,
|
||||
SMO_view_to_apiclip_x,
|
||||
};
|
||||
|
||||
enum ShaderArgType {
|
||||
SAT_float1,
|
||||
SAT_float2,
|
||||
|
|
@ -69,51 +107,6 @@ public:
|
|||
SAD_unknown,
|
||||
};
|
||||
|
||||
enum ShaderMatOp {
|
||||
SMO_identity,
|
||||
|
||||
SMO_modelview,
|
||||
SMO_projection,
|
||||
SMO_modelproj,
|
||||
|
||||
SMO_window_size,
|
||||
SMO_pixel_size,
|
||||
SMO_card_center,
|
||||
|
||||
SMO_mat_constant_x,
|
||||
SMO_vec_constant_x,
|
||||
|
||||
SMO_world_to_view,
|
||||
SMO_view_to_world_C,
|
||||
|
||||
SMO_model_to_view,
|
||||
SMO_view_to_model_C,
|
||||
|
||||
SMO_apiview_to_view,
|
||||
SMO_view_to_apiview_C,
|
||||
|
||||
SMO_clip_to_view,
|
||||
SMO_view_to_clip_C,
|
||||
|
||||
SMO_apiclip_to_view,
|
||||
SMO_view_to_apiclip_C,
|
||||
|
||||
SMO_view_x_to_view,
|
||||
SMO_view_to_view_x_C,
|
||||
|
||||
SMO_apiview_x_to_view,
|
||||
SMO_view_to_apiview_x_C,
|
||||
|
||||
SMO_clip_x_to_view,
|
||||
SMO_view_to_clip_x_C,
|
||||
|
||||
SMO_apiclip_x_to_view,
|
||||
SMO_view_to_apiclip_x_C,
|
||||
|
||||
SMO_transpose,
|
||||
SMO_noop,
|
||||
};
|
||||
|
||||
enum ShaderMatPiece {
|
||||
SMP_whole,
|
||||
SMP_transpose,
|
||||
|
|
@ -127,12 +120,21 @@ public:
|
|||
SMP_col3,
|
||||
};
|
||||
|
||||
enum ShaderMatFunc {
|
||||
SMF_compose,
|
||||
SMF_compose_cache_first,
|
||||
SMF_compose_cache_second,
|
||||
SMF_first,
|
||||
};
|
||||
|
||||
struct ShaderMatSpec {
|
||||
pvector<ShaderMatOp> _opcodes;
|
||||
pvector<PT(InternalName)> _args;
|
||||
ShaderMatPiece _piece;
|
||||
bool _trans_dependent;
|
||||
void *_parameter;
|
||||
ShaderMatFunc _func;
|
||||
ShaderMatInput _part[2];
|
||||
PT(InternalName) _arg[2];
|
||||
LMatrix4f _cache;
|
||||
ShaderMatPiece _piece;
|
||||
bool _trans_dependent;
|
||||
void *_parameter;
|
||||
};
|
||||
|
||||
struct ShaderTexSpec {
|
||||
|
|
@ -174,10 +176,12 @@ private:
|
|||
bool cp_errchk_parameter_sampler(ShaderArgInfo &arg);
|
||||
bool cp_parse_trans_clause(ShaderArgInfo &arg,
|
||||
ShaderMatSpec &spec,
|
||||
int part,
|
||||
const vector_string &pieces,
|
||||
int &next,
|
||||
ShaderMatOp ofop,
|
||||
ShaderMatOp op);
|
||||
ShaderMatInput ofop,
|
||||
ShaderMatInput op);
|
||||
void cp_optimize_mat_spec(ShaderMatSpec &spec);
|
||||
|
||||
protected:
|
||||
bool compile_parameter(void *reference,
|
||||
|
|
|
|||
Loading…
Reference in New Issue