Support using setShaderInput with a light to bind to GLSL struct

This commit is contained in:
rdb
2015-02-08 01:42:11 +01:00
parent 392cff6fb6
commit dad8f79e96
18 changed files with 390 additions and 48 deletions

View File

@@ -1167,6 +1167,31 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
t = LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],s[3],p[0],p[1],p[2],0,d[0],d[1],d[2],cutoff);
return &t;
}
case Shader::SMO_light_ambient: {
LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
const LightAttrib *target_light = (const LightAttrib *)
_target_rs->get_attrib_def(LightAttrib::get_class_slot());
int num_on_lights = target_light->get_num_on_lights();
if (num_on_lights == 0) {
// There are no lights at all. This means, to follow the fixed-
// function model, we pretend there is an all-white ambient light.
t.set_row(3, LVecBase4(1, 1, 1, 1));
} else {
for (int li = 0; li < num_on_lights; li++) {
NodePath light = target_light->get_on_light(li);
nassertr(!light.is_empty(), &LMatrix4::zeros_mat());
Light *light_obj = light.node()->as_light();
nassertr(light_obj != (Light *)NULL, &LMatrix4::zeros_mat());
if (light_obj->get_type() == AmbientLight::get_class_type()) {
cur_ambient_light += light_obj->get_color();
}
}
t.set_row(3, cur_ambient_light);
}
return &t;
}
case Shader::SMO_texmat_x: {
const TexMatrixAttrib *tma = DCAST(TexMatrixAttrib, _target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot()));
const TextureAttrib *ta = DCAST(TextureAttrib, _target_rs->get_attrib_def(TextureAttrib::get_class_slot()));
@@ -1330,6 +1355,167 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
calc_projection_mat(lens)->get_mat();
return &t;
}
case Shader::SMO_vec_constant_x_attrib: {
// This system is not ideal. It will be improved in the future.
if (_target_shader->has_shader_input(name)) {
// There is an input specifying precisely this whole thing, with
// dot and all. Support this, even if only for backward compatibility.
const LVecBase4 &data = _target_shader->get_shader_input_vector(name);
t = LMatrix4(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;
}
const NodePath &np = _target_shader->get_shader_input_nodepath(name->get_parent());
nassertr(!np.is_empty(), &LMatrix4::ident_mat());
CPT_InternalName attrib = name->get_basename();
static const CPT_InternalName IN_ambient("ambient");
static const CPT_InternalName IN_diffuse("diffuse");
static const CPT_InternalName IN_specular("specular");
static const CPT_InternalName IN_position("position");
static const CPT_InternalName IN_spotDirection("spotDirection");
static const CPT_InternalName IN_spotCutoff("spotCutoff");
static const CPT_InternalName IN_spotCosCutoff("spotCosCutoff");
static const CPT_InternalName IN_spotExponent("spotExponent");
static const CPT_InternalName IN_constantAttenuation("constantAttenuation");
static const CPT_InternalName IN_linearAttenuation("linearAttenuation");
static const CPT_InternalName IN_quadraticAttenuation("quadraticAttenuation");
if (attrib == IN_ambient) {
#ifndef NDEBUG
Light *light = np.node()->as_light();
nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
#endif
// Lights don't currently have an ambient color in Panda3D.
// We still have to support the attribute.
t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
return &t;
} else if (attrib == IN_diffuse) {
Light *light = np.node()->as_light();
nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
LColor c = light->get_color();
c.componentwise_mult(_light_color_scale);
t.set_row(3, c);
return &t;
} else if (attrib == IN_specular) {
Light *light = np.node()->as_light();
nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
t.set_row(3, light->get_specular_color());
return &t;
} else if (attrib == IN_position) {
if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
DirectionalLight *light;
DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
LVector3 dir = -(light->get_direction() * transform->get_mat());
dir *= get_scene()->get_cs_world_transform()->get_mat();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,dir[0],dir[1],dir[2],0);
return &t;
} else {
LightLensNode *light;
DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
Lens *lens = light->get_lens();
nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
CPT(TransformState) transform =
get_scene()->get_cs_world_transform()->compose(
np.get_transform(_scene_setup->get_scene_root().get_parent()));
const LMatrix4 &light_mat = transform->get_mat();
LPoint3 pos = lens->get_nodal_point() * light_mat;
t = LMatrix4::translate_mat(pos);
return &t;
}
} else if (attrib == IN_spotDirection) {
LightLensNode *light;
DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
Lens *lens = light->get_lens();
nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
CPT(TransformState) transform =
get_scene()->get_cs_world_transform()->compose(
np.get_transform(_scene_setup->get_scene_root().get_parent()));
const LMatrix4 &light_mat = transform->get_mat();
LVector3 dir = lens->get_view_vector() * light_mat;
t.set_row(3, dir);
return &t;
} else if (attrib == IN_spotCutoff) {
if (np.node()->is_of_type(Spotlight::get_class_type())) {
LightLensNode *light;
DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
Lens *lens = light->get_lens();
nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
float cutoff = lens->get_hfov() * 0.5f;
t.set_row(3, LVecBase4(cutoff));
return &t;
} else {
// Other lights have no cut-off.
t.set_row(3, LVecBase4(180));
return &t;
}
} else if (attrib == IN_spotCosCutoff) {
if (np.node()->is_of_type(Spotlight::get_class_type())) {
LightLensNode *light;
DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
Lens *lens = light->get_lens();
nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
float cutoff = lens->get_hfov() * 0.5f;
t.set_row(3, LVecBase4(ccos(deg_2_rad(cutoff))));
return &t;
} else {
// Other lights have no cut-off.
t.set_row(3, LVecBase4(-1));
return &t;
}
} else if (attrib == IN_spotExponent) {
Light *light = np.node()->as_light();
nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
t.set_row(3, LVecBase4(light->get_exponent()));
return &t;
} else if (attrib == IN_constantAttenuation) {
Light *light = np.node()->as_light();
nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
t.set_row(3, LVecBase4(light->get_attenuation()[0]));
return &t;
} else if (attrib == IN_linearAttenuation) {
Light *light = np.node()->as_light();
nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
t.set_row(3, LVecBase4(light->get_attenuation()[1]));
return &t;
} else if (attrib == IN_quadraticAttenuation) {
Light *light = np.node()->as_light();
nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
t.set_row(3, LVecBase4(light->get_attenuation()[2]));
return &t;
} else {
display_cat.error()
<< "Shader input requests invalid attribute " << *name
<< " from node " << np << "\n";
return &LMatrix4::ident_mat();
}
}
default:
nassertr(false /*should never get here*/, &LMatrix4::ident_mat());
return &LMatrix4::ident_mat();

View File

@@ -4220,8 +4220,8 @@ issue_memory_barrier(GLbitfield barriers) {
PStatGPUTimer timer(this, _memory_barrier_pcollector);
if (GLCAT.is_debug()) {
GLCAT.debug() << "Issuing memory barriers:";
if (GLCAT.is_spam()) {
GLCAT.spam() << "Issuing memory barriers:";
}
_glMemoryBarrier(barriers);
@@ -4230,25 +4230,25 @@ issue_memory_barrier(GLbitfield barriers) {
// the relevant lists of textures.
if (barriers & GL_TEXTURE_FETCH_BARRIER_BIT) {
_textures_needing_fetch_barrier.clear();
GLCAT.debug(false) << " texture_fetch";
GLCAT.spam(false) << " texture_fetch";
}
if (barriers & GL_SHADER_IMAGE_ACCESS_BARRIER_BIT) {
_textures_needing_image_access_barrier.clear();
GLCAT.debug(false) << " shader_image_access";
GLCAT.spam(false) << " shader_image_access";
}
if (barriers & GL_TEXTURE_UPDATE_BARRIER_BIT) {
_textures_needing_update_barrier.clear();
GLCAT.debug(false) << " texture_update";
GLCAT.spam(false) << " texture_update";
}
if (barriers & GL_FRAMEBUFFER_BARRIER_BIT) {
_textures_needing_framebuffer_barrier.clear();
GLCAT.debug(false) << " framebuffer";
GLCAT.spam(false) << " framebuffer";
}
GLCAT.debug(false) << "\n";
GLCAT.spam(false) << "\n";
report_my_gl_errors();
#endif // OPENGLES
@@ -8989,6 +8989,11 @@ set_state_and_transform(const RenderState *target,
//PStatGPUTimer timer(this, _draw_set_state_light_pcollector);
do_issue_light();
_state_mask.set_bit(light_slot);
#ifndef OPENGLES_1
if (_current_shader_context) {
_current_shader_context->issue_parameters(Shader::SSD_light);
}
#endif
}
int stencil_slot = StencilAttrib::get_class_slot();

View File

@@ -412,6 +412,20 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
s->_mat_spec.push_back(bind);
continue;
}
if (noprefix == "LightModel.ambient") {
Shader::ShaderMatSpec bind;
bind._id = arg_id;
bind._piece = Shader::SMP_row3;
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_light_ambient;
bind._arg[0] = NULL;
bind._dep[0] = Shader::SSD_general | Shader::SSD_light;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = NULL;
bind._dep[1] = Shader::SSD_NONE;
s->_mat_spec.push_back(bind);
continue;
}
GLCAT.error() << "Unrecognized uniform name '" << param_name_cstr << "'!\n";
continue;
@@ -565,7 +579,8 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
bind._arg[1] = NULL;
bind._dep[1] = Shader::SSD_NONE;
s->_mat_spec.push_back(bind);
continue; }
continue;
}
case GL_FLOAT_MAT4: {
Shader::ShaderMatSpec bind;
bind._id = arg_id;
@@ -578,7 +593,43 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
bind._arg[1] = NULL;
bind._dep[1] = Shader::SSD_NONE;
s->_mat_spec.push_back(bind);
continue; }
continue;
}
case GL_FLOAT:
case GL_FLOAT_VEC2:
case GL_FLOAT_VEC3:
case GL_FLOAT_VEC4: {
PT(InternalName) iname = InternalName::make(param_name);
if (iname->get_parent() != InternalName::get_root()) {
// It might be something like an attribute of a shader
// input, like a light parameter. It might also just be
// a custom struct parameter. We can't know yet, sadly.
Shader::ShaderMatSpec bind;
bind._id = arg_id;
switch (param_type) {
case GL_FLOAT:
bind._piece = Shader::SMP_row3x1;
break;
case GL_FLOAT_VEC2:
bind._piece = Shader::SMP_row3x2;
break;
case GL_FLOAT_VEC3:
bind._piece = Shader::SMP_row3x3;
break;
default:
bind._piece = Shader::SMP_row3;
}
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_vec_constant_x_attrib;
bind._arg[0] = iname;
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = NULL;
bind._dep[1] = Shader::SSD_NONE;
s->_mat_spec.push_back(bind);
continue;
} // else fall through
}
case GL_BOOL:
case GL_BOOL_VEC2:
case GL_BOOL_VEC3:
@@ -586,11 +637,7 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
case GL_INT:
case GL_INT_VEC2:
case GL_INT_VEC3:
case GL_INT_VEC4:
case GL_FLOAT:
case GL_FLOAT_VEC2:
case GL_FLOAT_VEC3:
case GL_FLOAT_VEC4: {
case GL_INT_VEC4: {
Shader::ShaderPtrSpec bind;
bind._id = arg_id;
switch (param_type) {

View File

@@ -423,6 +423,7 @@ cp_dependency(ShaderMatInput inp) {
(inp == SMO_satten_x) ||
(inp == SMO_mat_constant_x) ||
(inp == SMO_vec_constant_x) ||
(inp == SMO_vec_constant_x_attrib) ||
(inp == SMO_clipplane_x) ||
(inp == SMO_view_x_to_view) ||
(inp == SMO_view_to_view_x) ||
@@ -434,6 +435,15 @@ cp_dependency(ShaderMatInput inp) {
(inp == SMO_view_to_apiclip_x)) {
dep |= SSD_shaderinputs;
}
if ((inp == SMO_light_ambient) ||
(inp == SMO_light_source_i_attrib)) {
dep |= SSD_light;
}
if ((inp == SMO_light_product_i_ambient) ||
(inp == SMO_light_product_i_diffuse) ||
(inp == SMO_light_product_i_specular)) {
dep |= (SSD_light | SSD_material);
}
return dep;
}

View File

@@ -173,6 +173,16 @@ public:
SMO_frame_time,
SMO_frame_delta,
SMO_mat_constant_x_attrib,
SMO_vec_constant_x_attrib,
SMO_light_ambient,
SMO_light_source_i_attrib,
SMO_light_product_i_ambient,
SMO_light_product_i_diffuse,
SMO_light_product_i_specular,
SMO_INVALID
};
@@ -250,6 +260,7 @@ public:
SSD_material = 0x010,
SSD_shaderinputs = 0x020,
SSD_fog = 0x040,
SSD_light = 0x080,
};
enum ShaderBug {
@@ -337,13 +348,14 @@ public:
};
struct ShaderMatSpec {
LMatrix4 _cache[2];
LMatrix4 _value;
ShaderArgId _id;
ShaderMatFunc _func;
ShaderMatInput _part[2];
PT(InternalName) _arg[2];
int _dep[2];
LMatrix4 _cache[2];
LMatrix4 _value;
int _index;
ShaderMatPiece _piece;
};

View File

@@ -59,7 +59,7 @@ fillin(DatagramIterator &scan, BamReader *) {
////////////////////////////////////////////////////////////////////
// Function: Light::Destructor
// Access: Published, Virtual
// Description:
// Description:
////////////////////////////////////////////////////////////////////
Light::
~Light() {
@@ -76,6 +76,45 @@ is_ambient_light() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: Light::get_exponent
// Access: Public, Virtual
// Description: For spotlights, returns the exponent that controls
// the amount of light falloff from the center of the
// spotlight. For other kinds of lights, returns 0.
////////////////////////////////////////////////////////////////////
PN_stdfloat Light::
get_exponent() const {
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: Light::get_specular_color
// Access: Public, Virtual
// Description: Returns the color of specular highlights generated
// by the light. This value is meaningless for ambient
// lights.
////////////////////////////////////////////////////////////////////
const LColor &Light::
get_specular_color() const {
static const LColor white(1, 1, 1, 1);
return white;
}
////////////////////////////////////////////////////////////////////
// Function: Light::get_attenuation
// Access: Public, Virtual
// Description: Returns the terms of the attenuation equation for the
// light. These are, in order, the constant, linear,
// and quadratic terms based on the distance from the
// point to the vertex.
////////////////////////////////////////////////////////////////////
const LVecBase3 &Light::
get_attenuation() const {
static const LVecBase3 no_atten(1, 0, 0);
return no_atten;
}
////////////////////////////////////////////////////////////////////
// Function: Light::get_vector_to_light
// Access: Public, Virtual

View File

@@ -51,6 +51,10 @@ PUBLISHED:
INLINE const LColor &get_color() const;
INLINE void set_color(const LColor &color);
virtual PN_stdfloat get_exponent() const;
virtual const LColor &get_specular_color() const;
virtual const LVecBase3 &get_attenuation() const;
INLINE void set_priority(int priority);
INLINE int get_priority() const;
virtual int get_class_priority() const=0;

View File

@@ -113,6 +113,17 @@ get_flag(int index) const {
return (_flags & (1<<index)) ? true:false;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::has_shader_input
// Access: Published
// Description: Returns true if there is a ShaderInput of the given
// name.
////////////////////////////////////////////////////////////////////
bool ShaderAttrib::
has_shader_input(CPT_InternalName id) const {
return (_inputs.find(id) != _inputs.end());
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published

View File

@@ -340,7 +340,7 @@ get_shader_input_nodepath(const InternalName *id) const {
// Description: Returns the ShaderInput as a vector. Assertion
// fails if there is none, or if it is not a vector.
////////////////////////////////////////////////////////////////////
const LVecBase4 &ShaderAttrib::
LVecBase4 ShaderAttrib::
get_shader_input_vector(InternalName *id) const {
static LVecBase4 resfail(0,0,0,0);
Inputs::const_iterator i = _inputs.find(id);
@@ -352,9 +352,34 @@ get_shader_input_vector(InternalName *id) const {
} else {
const ShaderInput *p = (*i).second;
if (p->get_value_type() == ShaderInput::M_numeric) {
if (p->get_value_type() == ShaderInput::M_vector) {
return p->get_vector();
} else if (p->get_value_type() == ShaderInput::M_numeric && p->get_ptr()._size <= 4) {
const Shader::ShaderPtrData &ptr = p->get_ptr();
switch (ptr._type) {
case Shader::SPT_float:
{
LVector4f vectorf;
memcpy(&vectorf[0], ptr._ptr, sizeof(float) * ptr._size);
return LCAST(PN_stdfloat, vectorf);
}
case Shader::SPT_double:
{
LVector4d vectord;
memcpy(&vectord[0], ptr._ptr, sizeof(double) * ptr._size);
return LCAST(PN_stdfloat, vectord);
}
default:
{
ostringstream strm;
strm << "Shader input " << id->get_name() << " does not contain floating-point data.\n";
nassert_raise(strm.str());
return resfail;
}
}
} else if (p->get_value_type() == ShaderInput::M_param) {
// Temporary solution until the new param system
ParamValueBase *param = p->get_param();
@@ -387,7 +412,8 @@ get_shader_input_ptr(const InternalName *id) const {
return NULL;
} else {
const ShaderInput *p = (*i).second;
if (p->get_value_type() != ShaderInput::M_numeric) {
if (p->get_value_type() != ShaderInput::M_numeric &&
p->get_value_type() != ShaderInput::M_vector) {
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not a PTA(float/double) type.\n";
nassert_raise(strm.str());

View File

@@ -98,13 +98,14 @@ PUBLISHED:
CPT(RenderAttrib) clear_all_shader_inputs() const;
INLINE bool get_flag(int flag) const;
INLINE bool has_shader_input(CPT_InternalName id) const;
const Shader *get_shader() const;
const ShaderInput *get_shader_input(const InternalName *id) const;
const ShaderInput *get_shader_input(const string &id) const;
const NodePath &get_shader_input_nodepath(const InternalName *id) const;
const LVecBase4 &get_shader_input_vector(InternalName *id) const;
LVecBase4 get_shader_input_vector(InternalName *id) const;
Texture *get_shader_input_texture(const InternalName *id) const;
const SamplerState &get_shader_input_sampler(const InternalName *id) const;
const Shader::ShaderPtrData *get_shader_input_ptr(const InternalName *id) const;

View File

@@ -212,7 +212,7 @@ ShaderInput(CPT_InternalName name, const PTA_LVecBase2f &ptr, int priority) :
INLINE ShaderInput::
ShaderInput(CPT_InternalName name, const LVecBase4f &vec, int priority) :
_name(MOVE(name)),
_type(M_numeric),
_type(M_vector),
_priority(priority),
_stored_ptr(vec),
_stored_vector(LCAST(PN_stdfloat, vec)),
@@ -230,7 +230,7 @@ ShaderInput(CPT_InternalName name, const LVecBase4f &vec, int priority) :
INLINE ShaderInput::
ShaderInput(CPT_InternalName name, const LVecBase3f &vec, int priority) :
_name(MOVE(name)),
_type(M_numeric),
_type(M_vector),
_priority(priority),
_stored_ptr(vec),
_stored_vector(vec.get_x(), vec.get_y(), vec.get_z(), 0.0),
@@ -248,7 +248,7 @@ ShaderInput(CPT_InternalName name, const LVecBase3f &vec, int priority) :
INLINE ShaderInput::
ShaderInput(CPT_InternalName name, const LVecBase2f &vec, int priority) :
_name(MOVE(name)),
_type(M_numeric),
_type(M_vector),
_priority(priority),
_stored_ptr(vec),
_stored_vector(vec.get_x(), vec.get_y(), 0.0, 0.0),

View File

@@ -94,6 +94,7 @@ PUBLISHED:
M_invalid = 0,
M_texture,
M_nodepath,
M_vector,
M_numeric,
M_texture_sampler,
M_param

View File

@@ -41,7 +41,7 @@ CData(const DirectionalLight::CData &copy) :
////////////////////////////////////////////////////////////////////
// Function: DirectionalLight::get_specular_color
// Access: Public
// Access: Public, Final
// Description: Returns the color of specular highlights generated by
// the light.
////////////////////////////////////////////////////////////////////

View File

@@ -37,21 +37,21 @@ public:
virtual void write(ostream &out, int indent_level) const;
virtual bool get_vector_to_light(LVector3 &result,
const LPoint3 &from_object_point,
const LPoint3 &from_object_point,
const LMatrix4 &to_object_space);
PUBLISHED:
INLINE const LColor &get_specular_color() const;
INLINE const LColor &get_specular_color() const FINAL;
INLINE void set_specular_color(const LColor &color);
INLINE const LPoint3 &get_point() const;
INLINE void set_point(const LPoint3 &point);
INLINE const LVector3 &get_direction() const;
INLINE void set_direction(const LVector3 &direction);
virtual int get_class_priority() const;
public:
virtual void bind(GraphicsStateGuardianBase *gsg, const NodePath &light,
int light_id);

View File

@@ -41,7 +41,7 @@ CData(const PointLight::CData &copy) :
////////////////////////////////////////////////////////////////////
// Function: PointLight::get_specular_color
// Access: Public
// Access: Public, Final
// Description: Returns the color of specular highlights generated by
// the light.
////////////////////////////////////////////////////////////////////
@@ -65,7 +65,7 @@ set_specular_color(const LColor &color) {
////////////////////////////////////////////////////////////////////
// Function: PointLight::get_attenuation
// Access: Public
// Access: Public, Final
// Description: Returns the terms of the attenuation equation for the
// light. These are, in order, the constant, linear,
// and quadratic terms based on the distance from the

View File

@@ -37,21 +37,21 @@ public:
virtual void write(ostream &out, int indent_level) const;
virtual bool get_vector_to_light(LVector3 &result,
const LPoint3 &from_object_point,
const LPoint3 &from_object_point,
const LMatrix4 &to_object_space);
PUBLISHED:
INLINE const LColor &get_specular_color() const;
INLINE const LColor &get_specular_color() const FINAL;
INLINE void set_specular_color(const LColor &color);
INLINE const LVecBase3 &get_attenuation() const;
INLINE const LVecBase3 &get_attenuation() const FINAL;
INLINE void set_attenuation(const LVecBase3 &attenuation);
INLINE const LPoint3 &get_point() const;
INLINE void set_point(const LPoint3 &point);
virtual int get_class_priority() const;
public:
virtual void bind(GraphicsStateGuardianBase *gsg, const NodePath &light,
int light_id);

View File

@@ -41,7 +41,7 @@ CData(const Spotlight::CData &copy) :
////////////////////////////////////////////////////////////////////
// Function: Spotlight::get_exponent
// Access: Public
// Access: Public, Final
// Description: Returns the exponent that controls the amount of
// light falloff from the center of the spotlight. See
// set_exponent().
@@ -71,7 +71,7 @@ set_exponent(PN_stdfloat exponent) {
////////////////////////////////////////////////////////////////////
// Function: Spotlight::get_specular_color
// Access: Public
// Access: Public, Final
// Description: Returns the color of specular highlights generated by
// the light.
////////////////////////////////////////////////////////////////////
@@ -95,7 +95,7 @@ set_specular_color(const LColor &color) {
////////////////////////////////////////////////////////////////////
// Function: Spotlight::get_attenuation
// Access: Public
// Access: Public, Final
// Description: Returns the terms of the attenuation equation for the
// light. These are, in order, the constant, linear,
// and quadratic terms based on the distance from the

View File

@@ -47,24 +47,24 @@ public:
virtual void write(ostream &out, int indent_level) const;
virtual bool get_vector_to_light(LVector3 &result,
const LPoint3 &from_object_point,
const LPoint3 &from_object_point,
const LMatrix4 &to_object_space);
PUBLISHED:
INLINE PN_stdfloat get_exponent() const;
INLINE PN_stdfloat get_exponent() const FINAL;
INLINE void set_exponent(PN_stdfloat exponent);
INLINE const LColor &get_specular_color() const;
INLINE const LColor &get_specular_color() const FINAL;
INLINE void set_specular_color(const LColor &color);
INLINE const LVecBase3 &get_attenuation() const;
INLINE const LVecBase3 &get_attenuation() const FINAL;
INLINE void set_attenuation(const LVecBase3 &attenuation);
virtual int get_class_priority() const;
static PT(Texture) make_spot(int pixel_width, PN_stdfloat full_radius,
LColor &fg, LColor &bg);
public:
virtual void bind(GraphicsStateGuardianBase *gsg, const NodePath &light,
int light_id);