don't expect a fixed number of lights

This commit is contained in:
David Rose 2002-07-11 23:10:40 +00:00
parent 5c0913c1ca
commit ab97742881
7 changed files with 70 additions and 64 deletions

View File

@ -337,6 +337,6 @@ get_coordinate_system() const {
////////////////////////////////////////////////////////////////////
INLINE Light *GraphicsStateGuardian::
get_light(int light_id) const {
nassertr(light_id >= 0 && light_id < _max_lights, (Light *)NULL);
nassertr(light_id >= 0 && light_id < (int)_light_info.size(), (Light *)NULL);
return _light_info[light_id]._light;
}

View File

@ -104,10 +104,6 @@ GraphicsStateGuardian(GraphicsWindow *win) {
_coordinate_system = default_coordinate_system;
_current_display_region = (DisplayRegion*)0L;
_current_lens = (Lens *)NULL;
_light_info = (LightInfo *)NULL;
_max_lights = 0;
reset();
}
@ -118,7 +114,6 @@ GraphicsStateGuardian(GraphicsWindow *win) {
////////////////////////////////////////////////////////////////////
GraphicsStateGuardian::
~GraphicsStateGuardian() {
init_lights(0);
}
////////////////////////////////////////////////////////////////////
@ -421,7 +416,7 @@ begin_frame() {
// to be reissued, in case their parameters or positions have
// changed between frames.
if (_lighting_enabled_this_frame) {
for (int i = 0; i < _max_lights; i++) {
for (int i = 0; i < (int)_light_info.size(); i++) {
if (_light_info[i]._enabled) {
enable_light(i, false);
_light_info[i]._enabled = false;
@ -688,13 +683,14 @@ issue_color(const ColorAttrib *attrib) {
// Function: GraphicsStateGuardian::issue_light
// Access: Public, Virtual
// Description: The default implementation of issue_light() assumes
// we have a limited number of equivalent hardware
// lights available (which were set up by the
// init_lights() call which should have been made in
// reset()). This function assigns each light to a
// we have a limited number of hardware lights
// available. This function assigns each light to a
// different hardware light id, trying to keep each
// light associated with the same id where possible, but
// reusing id's when necessary.
// reusing id's when necessary. When it is no longer
// possible to reuse existing id's (e.g. all id's are in
// use), slot_light() is called to prepare the next
// sequential light id.
//
// It will call apply_light() each time a light is
// assigned to a particular id for the first time in a
@ -710,17 +706,12 @@ issue_color(const ColorAttrib *attrib) {
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
issue_light(const LightAttrib *attrib) {
if (_max_lights == 0) {
// If we don't have any lights configured--no one called
// init_lights()--then forget it.
return;
}
// Initialize the current ambient light total and newly enabled
// light list
Colorf cur_ambient_light(0.0f, 0.0f, 0.0f, 1.0f);
int i;
for (i = 0; i < _max_lights; i++) {
int max_lights = (int)_light_info.size();
for (i = 0; i < max_lights; i++) {
_light_info[i]._next_enabled = false;
}
@ -750,7 +741,7 @@ issue_light(const LightAttrib *attrib) {
} else {
// Check to see if this light has already been bound to an id
int cur_light_id = -1;
for (i = 0; i < _max_lights; i++) {
for (i = 0; i < max_lights; i++) {
if (_light_info[i]._light == light) {
// Light has already been bound to an id, we only need to
// enable the light, not reapply it.
@ -764,7 +755,7 @@ issue_light(const LightAttrib *attrib) {
// See if there are any unbound light ids
if (cur_light_id == -1) {
for (i = 0; i < _max_lights; i++) {
for (i = 0; i < max_lights; i++) {
if (_light_info[i]._light == (Light *)NULL) {
_light_info[i]._light = light;
cur_light_id = i;
@ -776,7 +767,7 @@ issue_light(const LightAttrib *attrib) {
// If there were no unbound light ids, see if we can replace
// a currently unused but previously bound id
if (cur_light_id == -1) {
for (i = 0; i < _max_lights; i++) {
for (i = 0; i < max_lights; i++) {
if (!attrib->has_light(_light_info[i]._light)) {
_light_info[i]._light = light;
cur_light_id = i;
@ -784,6 +775,16 @@ issue_light(const LightAttrib *attrib) {
}
}
}
// If we *still* don't have a light id, slot a new one.
if (cur_light_id == -1) {
if (slot_new_light(max_lights)) {
cur_light_id = max_lights;
_light_info.push_back(LightInfo());
max_lights++;
nassertv(max_lights == (int)_light_info.size());
}
}
if (cur_light_id >= 0) {
enable_light(cur_light_id, true);
@ -807,7 +808,7 @@ issue_light(const LightAttrib *attrib) {
}
// Disable all unused lights
for (i = 0; i < _max_lights; i++) {
for (i = 0; i < max_lights; i++) {
if (!_light_info[i]._next_enabled) {
enable_light(i, false);
_light_info[i]._enabled = false;
@ -897,25 +898,21 @@ bind_light(Spotlight *light, int light_id) {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::init_lights
// Access: Protected
// Description: Should be called by a derived class, usually in the
// reset() function, to initialize the table of lights
// according to the number of hardware lights available.
// If the derived class overrides issue_light(), this
// function is not necessary.
// Function: GraphicsStateGuardian::slot_new_light
// Access: Protected, Virtual
// Description: This will be called by the base class before a
// particular light id will be used for the first time.
// It is intended to allow the derived class to reserve
// any additional resources, if required, for the new
// light; and also to indicate whether the hardware
// supports this many simultaneous lights.
//
// The return value should be true if the additional
// light is supported, or false if it is not.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
init_lights(int num_lights) {
if (_light_info != (LightInfo *)NULL) {
delete[] _light_info;
_light_info = (LightInfo *)NULL;
}
_max_lights = num_lights;
if (_max_lights > 0) {
_light_info = new LightInfo[_max_lights];
}
bool GraphicsStateGuardian::
slot_new_light(int light_id) {
return true;
}
////////////////////////////////////////////////////////////////////

View File

@ -155,7 +155,7 @@ public:
protected:
INLINE Light *get_light(int light_id) const;
void init_lights(int num_lights);
virtual bool slot_new_light(int light_id);
virtual void enable_lighting(bool enable);
virtual void set_ambient_light(const Colorf &color);
virtual void enable_light(int light_id, bool enable);
@ -282,8 +282,7 @@ private:
bool _next_enabled;
};
int _max_lights;
LightInfo *_light_info; // LightInfo[_max_lights]
pvector<LightInfo> _light_info;
bool _lighting_enabled_this_frame;
// NOTE: on win32 another DLL (e.g. libpandadx.dll) cannot access

View File

@ -93,11 +93,6 @@ typedef enum { NothingSet=0,NormalOnly,ColorOnly,Normal_Color,TexCoordOnly,
#define PER_COLOR ColorOnly
#define PER_TEXCOORD TexCoordOnly
// technically DX7's front-end has no limit on the number of lights, but it's simpler for
// this implementation to set a small GL-like limit to make the light array traversals short
// and so I dont have to write code that reallocs light arrays
#define DXGSG_MAX_LIGHTS 8
static D3DMATRIX matIdentity;
#ifdef COUNT_DRAWPRIMS
@ -716,14 +711,6 @@ dx_init( void) {
scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1);
// technically DX7's front-end has no limit on the number of lights, but it's simpler for
// this implementation to set a small GL-like limit to make the light array traversals short
// and so I dont have to write code that reallocs light arrays
assert((scrn.D3DDevDesc.dwMaxActiveLights==0) || // 0 means infinite lights
(DXGSG_MAX_LIGHTS <= scrn.D3DDevDesc.dwMaxActiveLights));
init_lights(DXGSG_MAX_LIGHTS);
if(dx_auto_normalize_lighting)
scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_NORMALIZENORMALS, true);

View File

@ -89,9 +89,6 @@ typedef enum { NothingSet=0,NormalOnly,ColorOnly,Normal_Color,TexCoordOnly,
#define PER_COLOR ColorOnly
#define PER_TEXCOORD TexCoordOnly
// DX8's SW front-end has no limit on the number of lights, but HW is usually limited to 8
#define DXGSG_MAX_LIGHTS 8
// xform mat for vshader will usually be loaded at constant regs c4-c7
#define VSHADER_XFORMMATRIX_CONSTANTREGNUMSTART 4
@ -773,12 +770,19 @@ dx_init(HCURSOR hMouseCursor) {
scrn.pD3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1); // Use the diffuse vertex color.
/*
Panda no longer requires us to specify the maximum number of
lights up front, but instead we can define slot_new_light() to
decide one-at-a-time whether a particular light fits within our
limit or not. Until we override this function, there is no
limit.
if(scrn.d3dcaps.MaxActiveLights==0) {
// 0 indicates no limit on # of lights, but we use DXGSG_MAX_LIGHTS anyway for now
init_lights(DXGSG_MAX_LIGHTS);
} else {
init_lights(min(DXGSG_MAX_LIGHTS,scrn.d3dcaps.MaxActiveLights));
}
} */
if(dx_auto_normalize_lighting)
scrn.pD3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, true);

View File

@ -251,10 +251,10 @@ reset() {
glEnable(GL_NORMALIZE);
}
// Set up the light id map
// Count the max number of lights
GLint max_lights;
glGetIntegerv(GL_MAX_LIGHTS, &max_lights);
init_lights(max_lights);
_max_lights = max_lights;
// Set up the clip plane id map
GLint max_clip_planes;
@ -3347,6 +3347,24 @@ issue_transformed_color(const Colorf &color) const {
glColor4fv(transformed.get_data());
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::slot_new_light
// Access: Protected, Virtual
// Description: This will be called by the base class before a
// particular light id will be used for the first time.
// It is intended to allow the derived class to reserve
// any additional resources, if required, for the new
// light; and also to indicate whether the hardware
// supports this many simultaneous lights.
//
// The return value should be true if the additional
// light is supported, or false if it is not.
////////////////////////////////////////////////////////////////////
bool GLGraphicsStateGuardian::
slot_new_light(int light_id) {
return (light_id < _max_lights);
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::enable_lighting
// Access: Protected, Virtual

View File

@ -146,6 +146,7 @@ public:
void issue_transformed_color(const Colorf &color) const;
protected:
virtual bool slot_new_light(int light_id);
virtual void enable_lighting(bool enable);
virtual void set_ambient_light(const Colorf &color);
virtual void enable_light(int light_id, bool enable);
@ -305,7 +306,7 @@ protected:
bool _polygon_offset_enabled;
int _decal_level;
int _cur_light_id;
int _max_lights;
LMatrix4f _current_projection_mat;
int _projection_mat_stack_count;