optimize light state a bit
This commit is contained in:
parent
c69c8680e8
commit
7b7b973a7a
|
|
@ -798,6 +798,8 @@ begin_scene() {
|
|||
void DXGraphicsStateGuardian8::
|
||||
end_scene() {
|
||||
GraphicsStateGuardian::end_scene();
|
||||
_dlights.clear();
|
||||
|
||||
HRESULT hr = _d3d_device->EndScene();
|
||||
|
||||
if (FAILED(hr)) {
|
||||
|
|
@ -2528,35 +2530,41 @@ bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
|
||||
// Get the light in "world coordinates" (actually, view
|
||||
// coordinates). This means the light in the coordinate space of
|
||||
// the camera, converted to DX's coordinate system.
|
||||
CPT(TransformState) transform = light.get_transform(_scene_setup->get_camera_path());
|
||||
const LMatrix4f &light_mat = transform->get_mat();
|
||||
LMatrix4f rel_mat = light_mat * LMatrix4f::convert_mat(CS_yup_left, CS_default);
|
||||
LVector3f dir = light_obj->get_direction() * rel_mat;
|
||||
static PStatCollector _draw_set_state_light_bind_directional_pcollector("Draw:Set State:Light:Bind:Directional");
|
||||
PStatTimer timer(_draw_set_state_light_bind_directional_pcollector);
|
||||
|
||||
D3DCOLORVALUE black;
|
||||
black.r = black.g = black.b = black.a = 0.0f;
|
||||
pair<DirectionalLights::iterator, bool> lookup = _dlights.insert(DirectionalLights::value_type(light, D3DLIGHT8()));
|
||||
D3DLIGHT8 &fdata = (*lookup.first).second;
|
||||
if (lookup.second) {
|
||||
// Get the light in "world coordinates" (actually, view
|
||||
// coordinates). This means the light in the coordinate space of
|
||||
// the camera, converted to DX's coordinate system.
|
||||
CPT(TransformState) transform = light.get_transform(_scene_setup->get_camera_path());
|
||||
const LMatrix4f &light_mat = transform->get_mat();
|
||||
LMatrix4f rel_mat = light_mat * LMatrix4f::convert_mat(CS_yup_left, CS_default);
|
||||
LVector3f dir = light_obj->get_direction() * rel_mat;
|
||||
|
||||
D3DCOLORVALUE black;
|
||||
black.r = black.g = black.b = black.a = 0.0f;
|
||||
|
||||
ZeroMemory(&fdata, sizeof(D3DLIGHT8));
|
||||
|
||||
fdata.Type = D3DLIGHT_DIRECTIONAL;
|
||||
fdata.Diffuse = get_light_color(light_obj);
|
||||
fdata.Ambient = black ;
|
||||
fdata.Specular = *(D3DCOLORVALUE *)(light_obj->get_specular_color().get_data());
|
||||
|
||||
fdata.Direction = *(D3DVECTOR *)dir.get_data();
|
||||
|
||||
fdata.Range = __D3DLIGHT_RANGE_MAX;
|
||||
fdata.Falloff = 1.0f;
|
||||
|
||||
fdata.Attenuation0 = 1.0f; // constant
|
||||
fdata.Attenuation1 = 0.0f; // linear
|
||||
fdata.Attenuation2 = 0.0f; // quadratic
|
||||
}
|
||||
|
||||
D3DLIGHT8 alight;
|
||||
ZeroMemory(&alight, sizeof(D3DLIGHT8));
|
||||
|
||||
alight.Type = D3DLIGHT_DIRECTIONAL;
|
||||
alight.Diffuse = get_light_color(light_obj);
|
||||
alight.Ambient = black ;
|
||||
alight.Specular = *(D3DCOLORVALUE *)(light_obj->get_specular_color().get_data());
|
||||
|
||||
alight.Direction = *(D3DVECTOR *)dir.get_data();
|
||||
|
||||
alight.Range = __D3DLIGHT_RANGE_MAX;
|
||||
alight.Falloff = 1.0f;
|
||||
|
||||
alight.Attenuation0 = 1.0f; // constant
|
||||
alight.Attenuation1 = 0.0f; // linear
|
||||
alight.Attenuation2 = 0.0f; // quadratic
|
||||
|
||||
HRESULT hr = _d3d_device->SetLight(light_id, &alight);
|
||||
HRESULT hr = _d3d_device->SetLight(light_id, &fdata);
|
||||
if (FAILED(hr)) {
|
||||
wdxdisplay8_cat.warning()
|
||||
<< "Could not set light properties for " << light
|
||||
|
|
|
|||
|
|
@ -252,6 +252,12 @@ protected:
|
|||
const DXIndexBufferContext8 *_active_ibuffer;
|
||||
|
||||
int _num_active_texture_stages;
|
||||
|
||||
// Cache the data necessary to bind each particular light each
|
||||
// frame, so if we bind a given light multiple times, we only have
|
||||
// to compute its data once.
|
||||
typedef pmap<NodePath, D3DLIGHT8> DirectionalLights;
|
||||
DirectionalLights _dlights;
|
||||
|
||||
bool _overlay_windows_supported;
|
||||
bool _tex_stats_retrieval_impossible;
|
||||
|
|
|
|||
|
|
@ -1146,6 +1146,8 @@ end_scene() {
|
|||
_current_shader_context = (CLP(ShaderContext) *)NULL;
|
||||
}
|
||||
|
||||
_dlights.clear();
|
||||
|
||||
/*
|
||||
HRESULT hr = _d3d_device->EndScene();
|
||||
|
||||
|
|
@ -3382,35 +3384,41 @@ bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian9::
|
||||
bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
|
||||
// Get the light in "world coordinates" (actually, view
|
||||
// coordinates). This means the light in the coordinate space of
|
||||
// the camera, converted to DX's coordinate system.
|
||||
CPT(TransformState) transform = light.get_transform(_scene_setup->get_camera_path());
|
||||
const LMatrix4f &light_mat = transform->get_mat();
|
||||
LMatrix4f rel_mat = light_mat * LMatrix4f::convert_mat(CS_yup_left, CS_default);
|
||||
LVector3f dir = light_obj->get_direction() * rel_mat;
|
||||
static PStatCollector _draw_set_state_light_bind_directional_pcollector("Draw:Set State:Light:Bind:Directional");
|
||||
PStatTimer timer(_draw_set_state_light_bind_directional_pcollector);
|
||||
|
||||
D3DCOLORVALUE black;
|
||||
black.r = black.g = black.b = black.a = 0.0f;
|
||||
pair<DirectionalLights::iterator, bool> lookup = _dlights.insert(DirectionalLights::value_type(light, D3DLIGHT9()));
|
||||
D3DLIGHT9 &fdata = (*lookup.first).second;
|
||||
if (lookup.second) {
|
||||
// Get the light in "world coordinates" (actually, view
|
||||
// coordinates). This means the light in the coordinate space of
|
||||
// the camera, converted to DX's coordinate system.
|
||||
CPT(TransformState) transform = light.get_transform(_scene_setup->get_camera_path());
|
||||
const LMatrix4f &light_mat = transform->get_mat();
|
||||
LMatrix4f rel_mat = light_mat * LMatrix4f::convert_mat(CS_yup_left, CS_default);
|
||||
LVector3f dir = light_obj->get_direction() * rel_mat;
|
||||
|
||||
D3DCOLORVALUE black;
|
||||
black.r = black.g = black.b = black.a = 0.0f;
|
||||
|
||||
ZeroMemory(&fdata, sizeof(D3DLIGHT9));
|
||||
|
||||
fdata.Type = D3DLIGHT_DIRECTIONAL;
|
||||
fdata.Diffuse = get_light_color(light_obj);
|
||||
fdata.Ambient = black ;
|
||||
fdata.Specular = *(D3DCOLORVALUE *)(light_obj->get_specular_color().get_data());
|
||||
|
||||
fdata.Direction = *(D3DVECTOR *)dir.get_data();
|
||||
|
||||
fdata.Range = __D3DLIGHT_RANGE_MAX;
|
||||
fdata.Falloff = 1.0f;
|
||||
|
||||
fdata.Attenuation0 = 1.0f; // constant
|
||||
fdata.Attenuation1 = 0.0f; // linear
|
||||
fdata.Attenuation2 = 0.0f; // quadratic
|
||||
}
|
||||
|
||||
D3DLIGHT9 alight;
|
||||
ZeroMemory(&alight, sizeof(D3DLIGHT9));
|
||||
|
||||
alight.Type = D3DLIGHT_DIRECTIONAL;
|
||||
alight.Diffuse = get_light_color(light_obj);
|
||||
alight.Ambient = black ;
|
||||
alight.Specular = *(D3DCOLORVALUE *)(light_obj->get_specular_color().get_data());
|
||||
|
||||
alight.Direction = *(D3DVECTOR *)dir.get_data();
|
||||
|
||||
alight.Range = __D3DLIGHT_RANGE_MAX;
|
||||
alight.Falloff = 1.0f;
|
||||
|
||||
alight.Attenuation0 = 1.0f; // constant
|
||||
alight.Attenuation1 = 0.0f; // linear
|
||||
alight.Attenuation2 = 0.0f; // quadratic
|
||||
|
||||
HRESULT hr = _d3d_device->SetLight(light_id, &alight);
|
||||
HRESULT hr = _d3d_device->SetLight(light_id, &fdata);
|
||||
if (FAILED(hr)) {
|
||||
wdxdisplay9_cat.warning()
|
||||
<< "Could not set light properties for " << light
|
||||
|
|
|
|||
|
|
@ -316,6 +316,12 @@ protected:
|
|||
|
||||
DWORD _last_fvf;
|
||||
|
||||
// Cache the data necessary to bind each particular light each
|
||||
// frame, so if we bind a given light multiple times, we only have
|
||||
// to compute its data once.
|
||||
typedef pmap<NodePath, D3DLIGHT9> DirectionalLights;
|
||||
DirectionalLights _dlights;
|
||||
|
||||
#define MAXIMUM_TEXTURES 16
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1631,6 +1631,8 @@ end_scene() {
|
|||
_current_shader = (Shader *)NULL;
|
||||
_current_shader_context = (CLP(ShaderContext) *)NULL;
|
||||
}
|
||||
|
||||
_dlights.clear();
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
|
|
@ -4176,6 +4178,15 @@ bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
|
|||
static PStatCollector _draw_set_state_light_bind_directional_pcollector("Draw:Set State:Light:Bind:Directional");
|
||||
PStatTimer timer(_draw_set_state_light_bind_directional_pcollector);
|
||||
|
||||
pair<DirectionalLights::iterator, bool> lookup = _dlights.insert(DirectionalLights::value_type(light, DirectionalLightFrameData()));
|
||||
DirectionalLightFrameData &fdata = (*lookup.first).second;
|
||||
if (lookup.second) {
|
||||
// The light was not computed yet this frame. Compute it now.
|
||||
CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
|
||||
LVector3f dir = light_obj->get_direction() * transform->get_mat();
|
||||
fdata._neg_dir.set(-dir[0], -dir[1], -dir[2], 0);
|
||||
}
|
||||
|
||||
float light_color[4];
|
||||
GLenum id = get_light_id( light_id );
|
||||
static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
|
@ -4185,10 +4196,7 @@ bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
|
|||
|
||||
// Position needs to specify x, y, z, and w.
|
||||
// w == 0 implies light is at infinity
|
||||
CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
|
||||
LVector3f dir = light_obj->get_direction() * transform->get_mat();
|
||||
LPoint4f fdir(-dir[0], -dir[1], -dir[2], 0);
|
||||
GLP(Lightfv)(id, GL_POSITION, fdir.get_data());
|
||||
GLP(Lightfv)(id, GL_POSITION, fdata._neg_dir.get_data());
|
||||
|
||||
// GL_SPOT_DIRECTION is not significant when cutoff == 180
|
||||
// In this case, position x, y, z specifies direction
|
||||
|
|
|
|||
|
|
@ -395,6 +395,16 @@ protected:
|
|||
bool _use_sender;
|
||||
#endif // SUPPORT_IMMEDIATE_MODE
|
||||
|
||||
// Cache the data necessary to bind each particular light each
|
||||
// frame, so if we bind a given light multiple times, we only have
|
||||
// to compute its data once.
|
||||
class DirectionalLightFrameData {
|
||||
public:
|
||||
LVector4f _neg_dir;
|
||||
};
|
||||
typedef pmap<NodePath, DirectionalLightFrameData> DirectionalLights;
|
||||
DirectionalLights _dlights;
|
||||
|
||||
int _pass_number;
|
||||
bool _auto_rescale_normal;
|
||||
GLuint _geom_display_list;
|
||||
|
|
|
|||
Loading…
Reference in New Issue