mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
don't expect a fixed number of lights
This commit is contained in:
parent
5c0913c1ca
commit
ab97742881
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user