latest from glgsg

This commit is contained in:
David Rose 2002-03-29 00:44:25 +00:00
parent 29afc8d547
commit 548b2c871d
5 changed files with 260 additions and 489 deletions

View File

@ -65,6 +65,11 @@ bool cr_save_mipmaps = config_crgsg.GetBool("cr-save-mipmaps", false);
// variable.
bool cr_auto_normalize_lighting = config_crgsg.GetBool("auto-normalize-lighting", false);
// Configure this true to try to implement decals using a
// DepthOffsetAttrib, false to do them with the more reliable 3-pass
// rendering method instead.
bool cr_depth_offset_decals = config_crgsg.GetBool("depth-offset-decals", false);
// Configure this true to indicate the current version of GL fully
// supports textures with B, G, R ordering; false if it only supports
// R, G, B. false will always work, but true might be faster if the

View File

@ -32,6 +32,7 @@ extern bool cr_force_mipmaps;
extern bool cr_show_mipmaps;
extern bool cr_save_mipmaps;
extern bool cr_auto_normalize_lighting;
extern bool cr_depth_offset_decals;
extern bool cr_supports_bgr;
// Ways to implement decals.

View File

@ -20,18 +20,6 @@
#include <graphicsWindow.h>
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::LightInfo::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CRGraphicsStateGuardian::LightInfo::
LightInfo() {
_light = (Light *)NULL;
_enabled = false;
_next_enabled = false;
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::activate
// Access: Public
@ -227,24 +215,6 @@ call_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
}
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::call_glLightModelAmbient
// Access:
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CRGraphicsStateGuardian::
call_glLightModelAmbient( const Colorf& color )
{
if (_lmodel_ambient != color) {
_lmodel_ambient = color;
#ifdef GSG_VERBOSE
crgsg_cat.debug()
<< "crLightModel(GL_LIGHT_MODEL_AMBIENT, " << color << ")" << endl;
#endif
chromium.LightModelfv(GL_LIGHT_MODEL_AMBIENT, color.get_data());
}
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::call_glLightModelLocal
// Access:
@ -733,32 +703,6 @@ enable_point_smooth(bool val) {
}
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::enable_lighting
// Access:
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CRGraphicsStateGuardian::
enable_lighting(bool val) {
if (_lighting_enabled != val) {
_lighting_enabled = val;
if (val) {
#ifdef GSG_VERBOSE
crgsg_cat.debug()
<< "crEnable(GL_LIGHTING)" << endl;
#endif
chromium.Enable(GL_LIGHTING);
_lighting_enabled_this_frame = true;
} else {
#ifdef GSG_VERBOSE
crgsg_cat.debug()
<< "crDisable(GL_LIGHTING)" << endl;
#endif
chromium.Disable(GL_LIGHTING);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::enable_dither
// Access:
@ -809,35 +753,6 @@ enable_stencil_test(bool val) {
}
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::enable_light
// Access:
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CRGraphicsStateGuardian::enable_light(int light, bool val)
{
if ( _light_info[light]._enabled != val )
{
_light_info[light]._enabled = val;
if ( val )
{
#ifdef GSG_VERBOSE
crgsg_cat.debug()
<< "crEnable(GL_LIGHT" << light << ")" << endl;
#endif
chromium.Enable( get_light_id( light ) );
}
else
{
#ifdef GSG_VERBOSE
crgsg_cat.debug()
<< "crDisable(GL_LIGHT" << light << ")" << endl;
#endif
chromium.Disable( get_light_id( light ) );
}
}
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::enable_texturing
// Access:

View File

@ -36,7 +36,6 @@
#include "lens.h"
#include "get_rel_pos.h"
#include "perspectiveLens.h"
#include "ambientLight.h"
#include "directionalLight.h"
#include "pointLight.h"
#include "spotlight.h"
@ -46,7 +45,6 @@
#include "colorMatrixTransition.h"
#include "alphaTransformTransition.h"
#include "colorTransition.h"
#include "lightTransition.h"
#include "textureTransition.h"
#include "renderModeTransition.h"
#include "materialTransition.h"
@ -66,6 +64,7 @@
#include "pointShapeTransition.h"
#include "polygonOffsetTransition.h"
#include "textureAttrib.h"
#include "lightAttrib.h"
#include "cullFaceAttrib.h"
#include "transparencyAttrib.h"
#include "depthTestAttrib.h"
@ -157,7 +156,6 @@ issue_transformed_color_gl(const Geom *geom, Geom::ColorIterator &citerator,
////////////////////////////////////////////////////////////////////
CRGraphicsStateGuardian::
CRGraphicsStateGuardian(GraphicsWindow *win) : GraphicsStateGuardian(win) {
_light_info = (LightInfo *)NULL;
_clip_plane_enabled = (bool *)NULL;
_cur_clip_plane_enabled = (bool *)NULL;
@ -261,8 +259,6 @@ reset() {
_line_smooth_enabled = false;
_point_smooth_enabled = false;
_scissor_enabled = false;
_lighting_enabled = false;
_lighting_enabled_this_frame = false;
_normals_enabled = false;
_texturing_enabled = false;
_multisample_alpha_one_enabled = false;
@ -294,9 +290,8 @@ reset() {
// Set up the light id map
GLint max_lights;
chromium.GetIntegerv( GL_MAX_LIGHTS, &max_lights );
_max_lights = max_lights;
_light_info = new LightInfo[_max_lights];
chromium.GetIntegerv(GL_MAX_LIGHTS, &max_lights);
init_lights(max_lights);
// Set up the clip plane id map
GLint max_clip_planes;
@ -319,15 +314,16 @@ reset() {
PT(DepthTestTransition) dta = new DepthTestTransition;
PT(DepthWriteTransition) dwa = new DepthWriteTransition;
PT(CullFaceTransition) cfa = new CullFaceTransition;
PT(LightTransition) la = new LightTransition;
PT(TextureTransition) ta = new TextureTransition;
dta->issue(this);
dwa->issue(this);
cfa->issue(this);
la->issue(this);
ta->issue(this);
Material empty;
apply_material(&empty);
if (cr_cheap_textures) {
crgsg_cat.info()
<< "Setting chromium.Hint() for fastest textures.\n";
@ -531,7 +527,6 @@ render_frame() {
_win->begin_frame();
report_errors();
_decal_level = 0;
_lighting_enabled_this_frame = false;
#ifdef DO_PSTATS
// For Pstats to track our current texture memory usage, we have to
@ -582,28 +577,6 @@ render_frame() {
// Now we're done with the frame processing. Clean up.
if (_lighting_enabled_this_frame) {
// Let's turn off all the lights we had on, and clear the light
// cache--to force the lights to be reissued next frame, in case
// their parameters or positions have changed between frames.
for (int i = 0; i < _max_lights; i++) {
enable_light(i, false);
_light_info[i]._light = (Light *)NULL;
}
// Also force the lighting state to unlit, so that issue_light()
// will be guaranteed to be called next frame even if we have the
// same set of light pointers we had this frame.
clear_attribute(LightTransition::get_class_type());
// All this work to undo the lighting state each frame doesn't seem
// ideal--there may be a better way. Maybe if the lights were just
// more aware of whether their parameters or positions have changed
// at all?
}
#ifndef NDEBUG
report_errors();
#endif
@ -1020,16 +993,9 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
// save the modelview matrix
const LMatrix4f &modelview_mat = _transform->get_mat();
// get the camera information
// Hmm, this doesn't work any more, since we don't store the camera
// pointer in new scene graph land. Need to find a better way to
// get the current window's aspect ratio. Here's a temporary hack
// for now.
// float aspect_ratio =
// get_current_camera()->get_lens()->get_aspect_ratio();
float aspect_ratio = 1.333333;
// We don't need to mess with the aspect ratio, since we are now
// using the default projection matrix, which has the right aspect
// ratio built in.
// load up our own matrices
chromium.MatrixMode(GL_MODELVIEW);
@ -1089,7 +1055,7 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
// y direction
if (y_overall)
scaled_height = geom->_y_texel_ratio[0] * half_height * aspect_ratio;
scaled_height = geom->_y_texel_ratio[0] * half_height;
else {
nassertv(((int)geom->_y_texel_ratio.size() >= geom->get_num_prims()));
y_walk = &geom->_y_texel_ratio[0];
@ -1171,7 +1137,7 @@ draw_sprite(GeomSprite *geom, GeomContext *) {
scaled_width = cur_image._x_ratio * half_width;
if (y_overall == false)
scaled_height = cur_image._y_ratio * half_height * aspect_ratio;
scaled_height = cur_image._y_ratio * half_height;
// if not G_OVERALL, do some trig for this z rotate
if (theta_on) {
@ -2087,7 +2053,6 @@ draw_texture(TextureContext *tc, const DisplayRegion *dr) {
TextureApplyTransition *taa = new TextureApplyTransition;
taa->set_mode(TextureApplyProperty::M_decal);
state.set_transition(new LightTransition);
state.set_transition(new ColorMaskTransition);
state.set_transition(new RenderModeTransition);
state.set_transition(new TexMatrixTransition);
@ -2303,7 +2268,6 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr,
prepare_display_region();
NodeTransitions state(na);
state.set_transition(new LightTransition);
state.set_transition(new TextureTransition);
state.set_transition(new TransformTransition);
//state.set_transition(new ColorBlendTransition);
@ -2522,196 +2486,6 @@ apply_fog(qpFog *fog) {
report_errors();
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::apply_light
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::apply_light( PointLight* light )
{
#if 0
// The light position will be relative to the current matrix, so
// we have to know what the current matrix is. Find a better
// solution later.
#ifdef GSG_VERBOSE
crgsg_cat.debug()
<< "crMatrixMode(GL_MODELVIEW)" << endl;
crgsg_cat.debug()
<< "crPushMatrix()" << endl;
crgsg_cat.debug()
<< "crLoadIdentity()" << endl;
#endif
chromium.MatrixMode(GL_MODELVIEW);
chromium.PushMatrix();
chromium.LoadMatrixf(LMatrix4f::convert_mat(_coordinate_system, CS_yup_right)
.get_data());
GLenum id = get_light_id( _cur_light_id );
Colorf black(0, 0, 0, 1);
chromium.Lightfv(id, GL_AMBIENT, black.get_data());
chromium.Lightfv(id, GL_DIFFUSE, light->get_color().get_data());
chromium.Lightfv(id, GL_SPECULAR, light->get_specular().get_data());
// Position needs to specify x, y, z, and w
// w == 1 implies non-infinite position
LPoint3f pos = get_rel_pos( light, _current_camera );
LPoint4f fpos( pos[0], pos[1], pos[2], 1 );
chromium.Lightfv( id, GL_POSITION, fpos.get_data() );
// GL_SPOT_DIRECTION is not significant when cutoff == 180
// Exponent == 0 implies uniform light distribution
chromium.Lightf( id, GL_SPOT_EXPONENT, 0 );
// Cutoff == 180 means uniform point light source
chromium.Lightf( id, GL_SPOT_CUTOFF, 180.0 );
chromium.Lightf( id, GL_CONSTANT_ATTENUATION,
light->get_constant_attenuation() );
chromium.Lightf( id, GL_LINEAR_ATTENUATION,
light->get_linear_attenuation() );
chromium.Lightf( id, GL_QUADRATIC_ATTENUATION,
light->get_quadratic_attenuation() );
chromium.PopMatrix();
#ifdef GSG_VERBOSE
crgsg_cat.debug()
<< "crPopMatrix()" << endl;
#endif
report_errors();
#endif
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::apply_light
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::apply_light( DirectionalLight* light )
{
#if 0
// The light position will be relative to the current matrix, so
// we have to know what the current matrix is. Find a better
// solution later.
#ifdef GSG_VERBOSE
crgsg_cat.debug()
<< "crMatrixMode(GL_MODELVIEW)" << endl;
crgsg_cat.debug()
<< "crPushMatrix()" << endl;
crgsg_cat.debug()
<< "crLoadIdentity()" << endl;
#endif
chromium.MatrixMode(GL_MODELVIEW);
chromium.PushMatrix();
chromium.LoadMatrixf(LMatrix4f::convert_mat(_coordinate_system, CS_yup_right)
.get_data());
GLenum id = get_light_id( _cur_light_id );
Colorf black(0, 0, 0, 1);
chromium.Lightfv(id, GL_AMBIENT, black.get_data());
chromium.Lightfv(id, GL_DIFFUSE, light->get_color().get_data());
chromium.Lightfv(id, GL_SPECULAR, light->get_specular().get_data());
// Position needs to specify x, y, z, and w
// w == 0 implies light is at infinity
LPoint3f dir = get_rel_forward( light, _current_camera,
_coordinate_system );
LPoint4f pos( -dir[0], -dir[1], -dir[2], 0 );
chromium.Lightfv( id, GL_POSITION, pos.get_data() );
// GL_SPOT_DIRECTION is not significant when cutoff == 180
// In this case, position x, y, z specifies direction
// Exponent == 0 implies uniform light distribution
chromium.Lightf( id, GL_SPOT_EXPONENT, 0 );
// Cutoff == 180 means uniform point light source
chromium.Lightf( id, GL_SPOT_CUTOFF, 180.0 );
// Default attenuation values (only spotlight can modify these)
chromium.Lightf( id, GL_CONSTANT_ATTENUATION, 1 );
chromium.Lightf( id, GL_LINEAR_ATTENUATION, 0 );
chromium.Lightf( id, GL_QUADRATIC_ATTENUATION, 0 );
chromium.PopMatrix();
#ifdef GSG_VERBOSE
crgsg_cat.debug()
<< "crPopMatrix()" << endl;
#endif
report_errors();
#endif
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::apply_light
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::apply_light( Spotlight* light )
{
#if 0
// The light position will be relative to the current matrix, so
// we have to know what the current matrix is. Find a better
// solution later.
#ifdef GSG_VERBOSE
crgsg_cat.debug()
<< "crMatrixMode(GL_MODELVIEW)" << endl;
crgsg_cat.debug()
<< "crPushMatrix()" << endl;
crgsg_cat.debug()
<< "crLoadIdentity()" << endl;
#endif
chromium.MatrixMode(GL_MODELVIEW);
chromium.PushMatrix();
chromium.LoadMatrixf(LMatrix4f::convert_mat(_coordinate_system, CS_yup_right)
.get_data());
GLenum id = get_light_id( _cur_light_id );
Colorf black(0, 0, 0, 1);
chromium.Lightfv(id, GL_AMBIENT, black.get_data());
chromium.Lightfv(id, GL_DIFFUSE, light->get_color().get_data());
chromium.Lightfv(id, GL_SPECULAR, light->get_specular().get_data());
// Position needs to specify x, y, z, and w
// w == 1 implies non-infinite position
LPoint3f pos = get_rel_pos( light, _current_camera );
LPoint4f fpos( pos[0], pos[1], pos[2], 1 );
chromium.Lightfv( id, GL_POSITION, fpos.get_data() );
chromium.Lightfv( id, GL_SPOT_DIRECTION,
get_rel_forward( light, _current_camera,
_coordinate_system ).get_data() );
chromium.Lightf( id, GL_SPOT_EXPONENT, light->get_exponent() );
chromium.Lightf( id, GL_SPOT_CUTOFF,
light->get_cutoff_angle() );
chromium.Lightf( id, GL_CONSTANT_ATTENUATION,
light->get_constant_attenuation() );
chromium.Lightf( id, GL_LINEAR_ATTENUATION,
light->get_linear_attenuation() );
chromium.Lightf( id, GL_QUADRATIC_ATTENUATION,
light->get_quadratic_attenuation() );
chromium.PopMatrix();
#ifdef GSG_VERBOSE
crgsg_cat.debug()
<< "crPopMatrix()" << endl;
#endif
report_errors();
#endif
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::apply_light
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::apply_light( AmbientLight* )
{
// Ambient lights are handled as a special case in issue_light().
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::issue_transform
// Access: Public, Virtual
@ -2726,36 +2500,6 @@ issue_transform(const TransformTransition *attrib) {
#endif
chromium.MatrixMode(GL_MODELVIEW);
chromium.LoadMatrixf(attrib->get_matrix().get_data());
#ifndef NDEBUG
if (cr_show_transforms) {
bool lighting_was_enabled = _lighting_enabled;
bool texturing_was_enabled = _texturing_enabled;
enable_lighting(false);
enable_texturing(false);
chromium.Begin(GL_LINES);
// X axis in red
chromium.Color3f(1.0f, 0.0f, 0.0f);
chromium.Vertex3f(0.0f, 0.0f, 0.0f);
chromium.Vertex3f(1.0f, 0.0f, 0.0f);
// Y axis in green
chromium.Color3f(0.0f, 1.0f, 0.0f);
chromium.Vertex3f(0.0f, 0.0f, 0.0f);
chromium.Vertex3f(0.0f, 1.0f, 0.0f);
// Z axis in blue
chromium.Color3f(0.0f, 0.0f, 1.0f);
chromium.Vertex3f(0.0f, 0.0f, 0.0f);
chromium.Vertex3f(0.0f, 0.0f, 1.0f);
chromium.End();
enable_lighting(lighting_was_enabled);
enable_texturing(texturing_was_enabled);
}
#endif
report_errors();
}
@ -2984,106 +2728,6 @@ issue_render_mode(const RenderModeTransition *attrib) {
report_errors();
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::issue_light
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::issue_light(const LightTransition *attrib )
{
nassertv(attrib->get_default_dir() != TD_on);
// activate();
// 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++) {
_light_info[i]._next_enabled = false;
}
int num_enabled = 0;
LightTransition::const_iterator li;
for (li = attrib->begin(); li != attrib->end(); ++li) {
Light *light = (*li).first;
nassertv(light != (Light *)NULL);
TransitionDirection dir = (*li).second;
if (dir == TD_on) {
num_enabled++;
enable_lighting(true);
if (light->get_light_type() == AmbientLight::get_class_type()) {
// Ambient lights don't require specific light ids; simply add
// in the ambient contribution to the current total
cur_ambient_light += light->get_color();
} else {
// Check to see if this light has already been bound to an id
_cur_light_id = -1;
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 apply it
_cur_light_id = -2;
enable_light(i, true);
_light_info[i]._next_enabled = true;
break;
}
}
// See if there are any unbound light ids
if (_cur_light_id == -1) {
for (i = 0; i < _max_lights; i++) {
if (_light_info[i]._light == (Light *)NULL) {
_light_info[i]._light = light;
_cur_light_id = i;
break;
}
}
}
// 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++) {
if (attrib->is_off(_light_info[i]._light)) {
_light_info[i]._light = light;
_cur_light_id = i;
break;
}
}
}
if (_cur_light_id >= 0) {
enable_light(_cur_light_id, true);
_light_info[i]._next_enabled = true;
// We need to do something different for each type of light
light->apply(this);
} else if (_cur_light_id == -1) {
crgsg_cat.error()
<< "issue_light() - failed to bind light to id" << endl;
}
}
}
}
// Disable all unused lights
for (i = 0; i < _max_lights; i++) {
if (!_light_info[i]._next_enabled)
enable_light(i, false);
}
// If no lights were enabled, disable lighting
if (num_enabled == 0) {
enable_lighting(false);
} else {
call_glLightModelAmbient(cur_ambient_light);
}
report_errors();
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::issue_color_blend
// Access: Public, Virtual
@ -3508,6 +3152,10 @@ issue_material(const MaterialAttrib *attrib) {
const Material *material = attrib->get_material();
if (material != (const Material *)NULL) {
apply_material(material);
} else {
// Apply a default material when materials are turned off.
Material empty;
apply_material(&empty);
}
report_errors();
}
@ -3718,9 +3366,9 @@ issue_depth_offset(const DepthOffsetAttrib *attrib) {
int offset = attrib->get_offset();
if (offset != 0) {
GLfloat newfactor = 1.0f;
GLfloat newunits = (GLfloat)offset;
chromium.PolygonOffset(newfactor, newunits);
// The relationship between these two parameters is a little
// unclear and poorly explained in the GL man pages.
chromium.PolygonOffset((GLfloat) -offset, (GLfloat) -offset);
enable_polygon_offset(true);
} else {
@ -3730,6 +3378,130 @@ issue_depth_offset(const DepthOffsetAttrib *attrib) {
report_errors();
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::bind_light
// Access: Public, Virtual
// Description: Called the first time a particular light has been
// bound to a given id within a frame, this should set
// up the associated hardware light with the light's
// properties.
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::
bind_light(PointLight *light, int light_id) {
GLenum id = get_light_id(light_id);
static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f);
chromium.Lightfv(id, GL_AMBIENT, black.get_data());
chromium.Lightfv(id, GL_DIFFUSE, light->get_color().get_data());
chromium.Lightfv(id, GL_SPECULAR, light->get_specular_color().get_data());
// Position needs to specify x, y, z, and w
// w == 1 implies non-infinite position
qpNodePath light_np(light);
const LMatrix4f &light_mat = light_np.get_mat(_scene_setup->get_scene_root());
LPoint3f pos = light->get_point() * light_mat;
LPoint4f fpos(pos[0], pos[1], pos[2], 1.0f);
chromium.Lightfv(id, GL_POSITION, fpos.get_data());
// GL_SPOT_DIRECTION is not significant when cutoff == 180
// Exponent == 0 implies uniform light distribution
chromium.Lightf(id, GL_SPOT_EXPONENT, 0.0f);
// Cutoff == 180 means uniform point light source
chromium.Lightf(id, GL_SPOT_CUTOFF, 180.0f);
const LVecBase3f &att = light->get_attenuation();
chromium.Lightf(id, GL_CONSTANT_ATTENUATION, att[0]);
chromium.Lightf(id, GL_LINEAR_ATTENUATION, att[1]);
chromium.Lightf(id, GL_QUADRATIC_ATTENUATION, att[2]);
report_errors();
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::bind_light
// Access: Public, Virtual
// Description: Called the first time a particular light has been
// bound to a given id within a frame, this should set
// up the associated hardware light with the light's
// properties.
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::
bind_light(DirectionalLight *light, int light_id) {
GLenum id = get_light_id( light_id );
static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f);
chromium.Lightfv(id, GL_AMBIENT, black.get_data());
chromium.Lightfv(id, GL_DIFFUSE, light->get_color().get_data());
chromium.Lightfv(id, GL_SPECULAR, light->get_specular_color().get_data());
// Position needs to specify x, y, z, and w.
// w == 0 implies light is at infinity
qpNodePath light_np(light);
const LMatrix4f &light_mat = light_np.get_mat(_scene_setup->get_scene_root());
LVector3f dir = light->get_direction() * light_mat;
LPoint4f fdir(-dir[0], -dir[1], -dir[2], 0);
chromium.Lightfv(id, GL_POSITION, fdir.get_data());
// GL_SPOT_DIRECTION is not significant when cutoff == 180
// In this case, position x, y, z specifies direction
// Exponent == 0 implies uniform light distribution
chromium.Lightf(id, GL_SPOT_EXPONENT, 0.0f);
// Cutoff == 180 means uniform point light source
chromium.Lightf(id, GL_SPOT_CUTOFF, 180.0f);
// Default attenuation values (only spotlight and point light can
// modify these)
chromium.Lightf(id, GL_CONSTANT_ATTENUATION, 1.0f);
chromium.Lightf(id, GL_LINEAR_ATTENUATION, 0.0f);
chromium.Lightf(id, GL_QUADRATIC_ATTENUATION, 0.0f);
report_errors();
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::bind_light
// Access: Public, Virtual
// Description: Called the first time a particular light has been
// bound to a given id within a frame, this should set
// up the associated hardware light with the light's
// properties.
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::
bind_light(Spotlight *light, int light_id) {
Lens *lens = light->get_lens();
nassertv(lens != (Lens *)NULL);
GLenum id = get_light_id(light_id);
static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f);
chromium.Lightfv(id, GL_AMBIENT, black.get_data());
chromium.Lightfv(id, GL_DIFFUSE, light->get_color().get_data());
chromium.Lightfv(id, GL_SPECULAR, light->get_specular_color().get_data());
// Position needs to specify x, y, z, and w
// w == 1 implies non-infinite position
qpNodePath light_np(light);
const LMatrix4f &light_mat = light_np.get_mat(_scene_setup->get_scene_root());
LPoint3f pos = lens->get_nodal_point() * light_mat;
LVector3f dir = lens->get_view_vector() * light_mat;
LPoint4f fpos(pos[0], pos[1], pos[2], 1.0f);
chromium.Lightfv(id, GL_POSITION, fpos.get_data());
chromium.Lightfv(id, GL_SPOT_DIRECTION, dir.get_data());
chromium.Lightf(id, GL_SPOT_EXPONENT, light->get_exponent());
chromium.Lightf(id, GL_SPOT_CUTOFF, lens->get_hfov());
const LVecBase3f &att = light->get_attenuation();
chromium.Lightf(id, GL_CONSTANT_ATTENUATION, att[0]);
chromium.Lightf(id, GL_LINEAR_ATTENUATION, att[1]);
chromium.Lightf(id, GL_QUADRATIC_ATTENUATION, att[2]);
report_errors();
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::wants_normals
// Access: Public, Virtual
@ -3895,6 +3667,19 @@ end_decal(GeomNode *base_geom) {
report_errors();
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::depth_offset_decals
// Access: Public, Virtual
// Description: Returns true if this GSG can implement decals using a
// DepthOffsetAttrib, or false if that is unreliable
// and the three-step rendering process should be used
// instead.
////////////////////////////////////////////////////////////////////
bool CRGraphicsStateGuardian::
depth_offset_decals() {
return cr_depth_offset_decals;
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::get_internal_coordinate_system
// Access: Public, Virtual
@ -4754,6 +4539,93 @@ issue_transformed_color(const Colorf &color) const {
chromium.Color4fv(transformed.get_data());
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::enable_lighting
// Access: Protected, Virtual
// Description: Intended to be overridden by a derived class to
// enable or disable the use of lighting overall. This
// is called by issue_light() according to whether any
// lights are in use or not.
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::
enable_lighting(bool enable) {
if (enable) {
chromium.Enable(GL_LIGHTING);
} else {
chromium.Disable(GL_LIGHTING);
}
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::set_ambient_light
// Access: Protected, Virtual
// Description: Intended to be overridden by a derived class to
// indicate the color of the ambient light that should
// be in effect. This is called by issue_light() after
// all other lights have been enabled or disabled.
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::
set_ambient_light(const Colorf &color) {
chromium.LightModelfv(GL_LIGHT_MODEL_AMBIENT, color.get_data());
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::enable_light
// Access: Protected, Virtual
// Description: Intended to be overridden by a derived class to
// enable the indicated light id. A specific Light will
// already have been bound to this id via bind_light().
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::
enable_light(int light_id, bool enable) {
if (enable) {
chromium.Enable(get_light_id(light_id));
} else {
chromium.Disable(get_light_id(light_id));
}
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::begin_bind_lights
// Access: Protected, Virtual
// Description: Called immediately before bind_light() is called,
// this is intended to provide the derived class a hook
// in which to set up some state (like transform) that
// might apply to several lights.
//
// The sequence is: begin_bind_lights() will be called,
// then one or more bind_light() calls, then
// end_bind_lights().
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::
begin_bind_lights() {
// We need to temporarily load a new matrix so we can define the
// light in a known coordinate system. We pick the transform of the
// root. (Alternatively, we could leave the current transform where
// it is and compute the light position relative to that transform
// instead of relative to the root, by composing with the matrix
// computed by _transform->invert_compose(render_transform). But I
// think loading a completely new matrix is simpler.)
chromium.MatrixMode(GL_MODELVIEW);
chromium.PushMatrix();
chromium.LoadMatrixf(_scene_setup->get_render_transform()->get_mat().get_data());
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::end_bind_lights
// Access: Protected, Virtual
// Description: Called after before bind_light() has been called one
// or more times (but before any geometry is issued or
// additional state is changed), this is intended to
// clean up any temporary changes to the state that may
// have been made by begin_bind_lights().
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::
end_bind_lights() {
chromium.MatrixMode(GL_MODELVIEW);
chromium.PopMatrix();
}
////////////////////////////////////////////////////////////////////
// Function: CRGraphicsStateGuardian::free_pointers
// Access: Protected
@ -4762,10 +4634,6 @@ issue_transformed_color(const Colorf &color) const {
////////////////////////////////////////////////////////////////////
void CRGraphicsStateGuardian::
free_pointers() {
if (_light_info != (LightInfo *)NULL) {
delete[] _light_info;
_light_info = (LightInfo *)NULL;
}
if (_clip_plane_enabled != (bool *)NULL) {
delete[] _clip_plane_enabled;
_clip_plane_enabled = (bool *)NULL;
@ -5044,10 +4912,6 @@ dump_state(void)
dump << "\t\t" << "GL_LINE_SMOOTH " << _line_smooth_enabled << " " << (bool)chromium.IsEnabled(GL_LINE_SMOOTH) << "\n";
dump << "\t\t" << "GL_POINT_SMOOTH " << _point_smooth_enabled << " " << (bool)chromium.IsEnabled(GL_POINT_SMOOTH) << "\n";
dump << "\t\t" << "GL_LIGHTING " << _lighting_enabled << " " << (bool)chromium.IsEnabled(GL_LIGHTING) << "\n";
for(i = 0; i < _max_lights; i++)
{
dump << "\t\t\t\t" << "GL_LIGHT" << i << " " << _light_info[i]._enabled << " " << (bool)chromium.IsEnabled(GL_LIGHT0+i) << "\n";
}
dump << "\t\t" << "GL_SCISSOR_TEST " << _scissor_enabled << " " << (bool)chromium.IsEnabled(GL_SCISSOR_TEST) << "\n";
dump << "\t\t" << "GL_TEXTURE_2D " << _texturing_enabled << " " << (bool)chromium.IsEnabled(GL_TEXTURE_2D) << "\n";
dump << "\t\t" << "GL_DITHER " << _dither_enabled << " " << (bool)chromium.IsEnabled(GL_DITHER) << "\n";

View File

@ -33,7 +33,6 @@
#include "depthTestProperty.h"
#include "stencilProperty.h"
#include "fog.h"
#include "pt_Light.h"
#include "depthTestAttrib.h"
#include "textureApplyAttrib.h"
#include "pointerToArray.h"
@ -141,18 +140,12 @@ public:
virtual void apply_fog(Fog *fog);
void apply_fog(qpFog *fog);
virtual void apply_light(PointLight* light);
virtual void apply_light(DirectionalLight* light);
virtual void apply_light(Spotlight* light);
virtual void apply_light(AmbientLight* light);
virtual void issue_transform(const TransformTransition *attrib);
virtual void issue_color_transform(const ColorMatrixTransition *attrib);
virtual void issue_alpha_transform(const AlphaTransformTransition *attrib);
virtual void issue_tex_matrix(const TexMatrixTransition *attrib);
virtual void issue_color(const ColorTransition *attrib);
virtual void issue_texture(const TextureTransition *attrib);
virtual void issue_light(const LightTransition *attrib);
virtual void issue_material(const MaterialTransition *attrib);
virtual void issue_render_mode(const RenderModeTransition *attrib);
virtual void issue_color_blend(const ColorBlendTransition *attrib);
@ -171,11 +164,8 @@ public:
virtual void issue_polygon_offset(const PolygonOffsetTransition *attrib);
virtual void issue_transform(const TransformState *transform);
// virtual void issue_color_scale(const ColorScaleAttrib *attrib);
// virtual void issue_color(const ColorAttrib *attrib);
virtual void issue_tex_matrix(const TexMatrixAttrib *attrib);
virtual void issue_texture(const TextureAttrib *attrib);
// virtual void issue_light(const LightAttrib *attrib);
virtual void issue_material(const MaterialAttrib *attrib);
virtual void issue_render_mode(const RenderModeAttrib *attrib);
virtual void issue_texture_apply(const TextureApplyAttrib *attrib);
@ -191,12 +181,18 @@ public:
// virtual void issue_stencil(const StencilAttrib *attrib);
// virtual void issue_clip_plane(const ClipPlaneAttrib *attrib);
virtual void bind_light(PointLight *light, int light_id);
virtual void bind_light(DirectionalLight *light, int light_id);
virtual void bind_light(Spotlight *light, int light_id);
virtual bool wants_normals(void) const;
virtual bool wants_texcoords(void) const;
virtual void begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib);
virtual void end_decal(GeomNode *base_geom);
virtual bool depth_offset_decals();
virtual CoordinateSystem get_internal_coordinate_system() const;
virtual float compute_distance_to(const LPoint3f &point) const;
@ -214,6 +210,12 @@ public:
void issue_transformed_color(const Colorf &color) const;
protected:
virtual void enable_lighting(bool enable);
virtual void set_ambient_light(const Colorf &color);
virtual void enable_light(int light_id, bool enable);
virtual void begin_bind_lights();
virtual void end_bind_lights();
void free_pointers();
virtual PT(SavedFrameBuffer) save_frame_buffer(const RenderBuffer &buffer,
CPT(DisplayRegion) dr);
@ -234,7 +236,6 @@ protected:
INLINE void call_glCullFace(GLenum mode);
INLINE void call_glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
INLINE void call_glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
INLINE void call_glLightModelAmbient(const Colorf& color);
INLINE void call_glLightModelLocal(GLboolean local);
INLINE void call_glLightModelTwoSide(GLboolean twoside);
INLINE void call_glStencilFunc(GLenum func,GLint refval,GLuint mask);
@ -256,8 +257,6 @@ protected:
INLINE void enable_multisample(bool val);
INLINE void enable_line_smooth(bool val);
INLINE void enable_point_smooth(bool val);
INLINE void enable_lighting(bool val);
INLINE void enable_light(int light, bool val);
INLINE void enable_texturing(bool val);
INLINE void enable_scissor(bool val);
INLINE void enable_dither(bool val);
@ -321,7 +320,6 @@ protected:
GLsizei _viewport_height;
GLboolean _lmodel_local;
GLboolean _lmodel_twoside;
Colorf _lmodel_ambient;
Colorf _material_ambient;
Colorf _material_diffuse;
Colorf _material_specular;
@ -350,8 +348,6 @@ protected:
bool _line_smooth_enabled;
bool _point_smooth_enabled;
bool _scissor_enabled;
bool _lighting_enabled;
bool _lighting_enabled_this_frame;
bool _texturing_enabled;
bool _dither_enabled;
bool _stencil_test_enabled;
@ -365,16 +361,6 @@ protected:
bool _polygon_offset_enabled;
int _decal_level;
class LightInfo {
public:
INLINE LightInfo();
PT_Light _light;
bool _enabled;
bool _next_enabled;
};
int _max_lights;
LightInfo *_light_info; // LightInfo[_max_lights]
int _cur_light_id;
LMatrix4f _current_projection_mat;